##// END OF EJS Templates
Fixes to testing....
Fernando Perez -
Show More
@@ -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 >>> Style(COLOR_RED, COLOR_BLACK)
65 <Style fg=red bg=black attrs=0>
64
66
65 >>> Style(COLOR_RED, COLOR_BLACK)
67 >>> Style(COLOR_YELLOW, COLOR_BLUE, A_BOLD|A_UNDERLINE)
66 >>> 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,2291 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 py> 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 py> import sys
53 >>> sys | ifilter("isinstance(value, int)") | idump
53 py> 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 py> 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 py> 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 py> 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 py> 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 import sys, os, os.path, stat, glob, new, csv, datetime, types
86 import sys, os, os.path, stat, glob, new, csv, datetime, types
87 import itertools, mimetypes, StringIO
87 import itertools, mimetypes, StringIO
88
88
89 try: # Python 2.3 compatibility
89 try: # Python 2.3 compatibility
90 import collections
90 import collections
91 except ImportError:
91 except ImportError:
92 deque = list
92 deque = list
93 else:
93 else:
94 deque = collections.deque
94 deque = collections.deque
95
95
96 try: # Python 2.3 compatibility
96 try: # Python 2.3 compatibility
97 set
97 set
98 except NameError:
98 except NameError:
99 import sets
99 import sets
100 set = sets.Set
100 set = sets.Set
101
101
102 try: # Python 2.3 compatibility
102 try: # Python 2.3 compatibility
103 sorted
103 sorted
104 except NameError:
104 except NameError:
105 def sorted(iterator, key=None, reverse=False):
105 def sorted(iterator, key=None, reverse=False):
106 items = list(iterator)
106 items = list(iterator)
107 if key is not None:
107 if key is not None:
108 items.sort(lambda i1, i2: cmp(key(i1), key(i2)))
108 items.sort(lambda i1, i2: cmp(key(i1), key(i2)))
109 else:
109 else:
110 items.sort()
110 items.sort()
111 if reverse:
111 if reverse:
112 items.reverse()
112 items.reverse()
113 return items
113 return items
114
114
115 try:
115 try:
116 import pwd
116 import pwd
117 except ImportError:
117 except ImportError:
118 pwd = None
118 pwd = None
119
119
120 try:
120 try:
121 import grp
121 import grp
122 except ImportError:
122 except ImportError:
123 grp = None
123 grp = None
124
124
125 from IPython.external import simplegeneric
125 from IPython.external import simplegeneric
126
126 from IPython.external import path
127 import path
128
127
129 try:
128 try:
130 from IPython import genutils, generics
129 from IPython import genutils, generics
131 except ImportError:
130 except ImportError:
132 genutils = None
131 genutils = None
133 generics = None
132 generics = None
134
133
135 from IPython import ipapi
134 from IPython import ipapi
136
135
137
136
138 __all__ = [
137 __all__ = [
139 "ifile", "ils", "iglob", "iwalk", "ipwdentry", "ipwd", "igrpentry", "igrp",
138 "ifile", "ils", "iglob", "iwalk", "ipwdentry", "ipwd", "igrpentry", "igrp",
140 "icsv", "ix", "ichain", "isort", "ifilter", "ieval", "ienum",
139 "icsv", "ix", "ichain", "isort", "ifilter", "ieval", "ienum",
141 "ienv", "ihist", "ialias", "icap", "idump", "iless"
140 "ienv", "ihist", "ialias", "icap", "idump", "iless"
142 ]
141 ]
143
142
144
143
145 os.stat_float_times(True) # enable microseconds
144 os.stat_float_times(True) # enable microseconds
146
145
147
146
148 class AttrNamespace(object):
147 class AttrNamespace(object):
149 """
148 """
150 Helper class that is used for providing a namespace for evaluating
149 Helper class that is used for providing a namespace for evaluating
151 expressions containing attribute names of an object.
150 expressions containing attribute names of an object.
152 """
151 """
153 def __init__(self, wrapped):
152 def __init__(self, wrapped):
154 self.wrapped = wrapped
153 self.wrapped = wrapped
155
154
156 def __getitem__(self, name):
155 def __getitem__(self, name):
157 if name == "_":
156 if name == "_":
158 return self.wrapped
157 return self.wrapped
159 try:
158 try:
160 return getattr(self.wrapped, name)
159 return getattr(self.wrapped, name)
161 except AttributeError:
160 except AttributeError:
162 raise KeyError(name)
161 raise KeyError(name)
163
162
164 # Python 2.3 compatibility
163 # Python 2.3 compatibility
165 # use eval workaround to find out which names are used in the
164 # 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
165 # eval string and put them into the locals. This works for most
167 # normal uses case, bizarre ones like accessing the locals()
166 # normal uses case, bizarre ones like accessing the locals()
168 # will fail
167 # will fail
169 try:
168 try:
170 eval("_", None, AttrNamespace(None))
169 eval("_", None, AttrNamespace(None))
171 except TypeError:
170 except TypeError:
172 real_eval = eval
171 real_eval = eval
173 def eval(codestring, _globals, _locals):
172 def eval(codestring, _globals, _locals):
174 """
173 """
175 eval(source[, globals[, locals]]) -> value
174 eval(source[, globals[, locals]]) -> value
176
175
177 Evaluate the source in the context of globals and locals.
176 Evaluate the source in the context of globals and locals.
178 The source may be a string representing a Python expression
177 The source may be a string representing a Python expression
179 or a code object as returned by compile().
178 or a code object as returned by compile().
180 The globals must be a dictionary and locals can be any mappping.
179 The globals must be a dictionary and locals can be any mappping.
181
180
182 This function is a workaround for the shortcomings of
181 This function is a workaround for the shortcomings of
183 Python 2.3's eval.
182 Python 2.3's eval.
184 """
183 """
185
184
186 if isinstance(codestring, basestring):
185 if isinstance(codestring, basestring):
187 code = compile(codestring, "_eval", "eval")
186 code = compile(codestring, "_eval", "eval")
188 else:
187 else:
189 code = codestring
188 code = codestring
190 newlocals = {}
189 newlocals = {}
191 for name in code.co_names:
190 for name in code.co_names:
192 try:
191 try:
193 newlocals[name] = _locals[name]
192 newlocals[name] = _locals[name]
194 except KeyError:
193 except KeyError:
195 pass
194 pass
196 return real_eval(code, _globals, newlocals)
195 return real_eval(code, _globals, newlocals)
197
196
198
197
199 noitem = object()
198 noitem = object()
200
199
201
200
202 def item(iterator, index, default=noitem):
201 def item(iterator, index, default=noitem):
203 """
202 """
204 Return the ``index``th item from the iterator ``iterator``.
203 Return the ``index``th item from the iterator ``iterator``.
205 ``index`` must be an integer (negative integers are relative to the
204 ``index`` must be an integer (negative integers are relative to the
206 end (i.e. the last items produced by the iterator)).
205 end (i.e. the last items produced by the iterator)).
207
206
208 If ``default`` is given, this will be the default value when
207 If ``default`` is given, this will be the default value when
209 the iterator doesn't contain an item at this position. Otherwise an
208 the iterator doesn't contain an item at this position. Otherwise an
210 ``IndexError`` will be raised.
209 ``IndexError`` will be raised.
211
210
212 Note that using this function will partially or totally exhaust the
211 Note that using this function will partially or totally exhaust the
213 iterator.
212 iterator.
214 """
213 """
215 i = index
214 i = index
216 if i>=0:
215 if i>=0:
217 for item in iterator:
216 for item in iterator:
218 if not i:
217 if not i:
219 return item
218 return item
220 i -= 1
219 i -= 1
221 else:
220 else:
222 i = -index
221 i = -index
223 cache = deque()
222 cache = deque()
224 for item in iterator:
223 for item in iterator:
225 cache.append(item)
224 cache.append(item)
226 if len(cache)>i:
225 if len(cache)>i:
227 cache.popleft()
226 cache.popleft()
228 if len(cache)==i:
227 if len(cache)==i:
229 return cache.popleft()
228 return cache.popleft()
230 if default is noitem:
229 if default is noitem:
231 raise IndexError(index)
230 raise IndexError(index)
232 else:
231 else:
233 return default
232 return default
234
233
235
234
236 def getglobals(g):
235 def getglobals(g):
237 """
236 """
238 Return the global namespace that is used for expression strings in
237 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
238 ``ifilter`` and others. This is ``g`` or (if ``g`` is ``None``) IPython's
240 user namespace.
239 user namespace.
241 """
240 """
242 if g is None:
241 if g is None:
243 if ipapi is not None:
242 if ipapi is not None:
244 api = ipapi.get()
243 api = ipapi.get()
245 if api is not None:
244 if api is not None:
246 return api.user_ns
245 return api.user_ns
247 return globals()
246 return globals()
248 return g
247 return g
249
248
250
249
251 class Descriptor(object):
250 class Descriptor(object):
252 """
251 """
253 A ``Descriptor`` object is used for describing the attributes of objects.
252 A ``Descriptor`` object is used for describing the attributes of objects.
254 """
253 """
255 def __hash__(self):
254 def __hash__(self):
256 return hash(self.__class__) ^ hash(self.key())
255 return hash(self.__class__) ^ hash(self.key())
257
256
258 def __eq__(self, other):
257 def __eq__(self, other):
259 return self.__class__ is other.__class__ and self.key() == other.key()
258 return self.__class__ is other.__class__ and self.key() == other.key()
260
259
261 def __ne__(self, other):
260 def __ne__(self, other):
262 return self.__class__ is not other.__class__ or self.key() != other.key()
261 return self.__class__ is not other.__class__ or self.key() != other.key()
263
262
264 def key(self):
263 def key(self):
265 pass
264 pass
266
265
267 def name(self):
266 def name(self):
268 """
267 """
269 Return the name of this attribute for display by a ``Display`` object
268 Return the name of this attribute for display by a ``Display`` object
270 (e.g. as a column title).
269 (e.g. as a column title).
271 """
270 """
272 key = self.key()
271 key = self.key()
273 if key is None:
272 if key is None:
274 return "_"
273 return "_"
275 return str(key)
274 return str(key)
276
275
277 def attrtype(self, obj):
276 def attrtype(self, obj):
278 """
277 """
279 Return the type of this attribute (i.e. something like "attribute" or
278 Return the type of this attribute (i.e. something like "attribute" or
280 "method").
279 "method").
281 """
280 """
282
281
283 def valuetype(self, obj):
282 def valuetype(self, obj):
284 """
283 """
285 Return the type of this attribute value of the object ``obj``.
284 Return the type of this attribute value of the object ``obj``.
286 """
285 """
287
286
288 def value(self, obj):
287 def value(self, obj):
289 """
288 """
290 Return the value of this attribute of the object ``obj``.
289 Return the value of this attribute of the object ``obj``.
291 """
290 """
292
291
293 def doc(self, obj):
292 def doc(self, obj):
294 """
293 """
295 Return the documentation for this attribute.
294 Return the documentation for this attribute.
296 """
295 """
297
296
298 def shortdoc(self, obj):
297 def shortdoc(self, obj):
299 """
298 """
300 Return a short documentation for this attribute (defaulting to the
299 Return a short documentation for this attribute (defaulting to the
301 first line).
300 first line).
302 """
301 """
303 doc = self.doc(obj)
302 doc = self.doc(obj)
304 if doc is not None:
303 if doc is not None:
305 doc = doc.strip().splitlines()[0].strip()
304 doc = doc.strip().splitlines()[0].strip()
306 return doc
305 return doc
307
306
308 def iter(self, obj):
307 def iter(self, obj):
309 """
308 """
310 Return an iterator for this attribute of the object ``obj``.
309 Return an iterator for this attribute of the object ``obj``.
311 """
310 """
312 return xiter(self.value(obj))
311 return xiter(self.value(obj))
313
312
314
313
315 class SelfDescriptor(Descriptor):
314 class SelfDescriptor(Descriptor):
316 """
315 """
317 A ``SelfDescriptor`` describes the object itself.
316 A ``SelfDescriptor`` describes the object itself.
318 """
317 """
319 def key(self):
318 def key(self):
320 return None
319 return None
321
320
322 def attrtype(self, obj):
321 def attrtype(self, obj):
323 return "self"
322 return "self"
324
323
325 def valuetype(self, obj):
324 def valuetype(self, obj):
326 return type(obj)
325 return type(obj)
327
326
328 def value(self, obj):
327 def value(self, obj):
329 return obj
328 return obj
330
329
331 def __repr__(self):
330 def __repr__(self):
332 return "Self"
331 return "Self"
333
332
334 selfdescriptor = SelfDescriptor() # there's no need for more than one
333 selfdescriptor = SelfDescriptor() # there's no need for more than one
335
334
336
335
337 class AttributeDescriptor(Descriptor):
336 class AttributeDescriptor(Descriptor):
338 """
337 """
339 An ``AttributeDescriptor`` describes a simple attribute of an object.
338 An ``AttributeDescriptor`` describes a simple attribute of an object.
340 """
339 """
341 __slots__ = ("_name", "_doc")
340 __slots__ = ("_name", "_doc")
342
341
343 def __init__(self, name, doc=None):
342 def __init__(self, name, doc=None):
344 self._name = name
343 self._name = name
345 self._doc = doc
344 self._doc = doc
346
345
347 def key(self):
346 def key(self):
348 return self._name
347 return self._name
349
348
350 def doc(self, obj):
349 def doc(self, obj):
351 return self._doc
350 return self._doc
352
351
353 def attrtype(self, obj):
352 def attrtype(self, obj):
354 return "attr"
353 return "attr"
355
354
356 def valuetype(self, obj):
355 def valuetype(self, obj):
357 return type(getattr(obj, self._name))
356 return type(getattr(obj, self._name))
358
357
359 def value(self, obj):
358 def value(self, obj):
360 return getattr(obj, self._name)
359 return getattr(obj, self._name)
361
360
362 def __repr__(self):
361 def __repr__(self):
363 if self._doc is None:
362 if self._doc is None:
364 return "Attribute(%r)" % self._name
363 return "Attribute(%r)" % self._name
365 else:
364 else:
366 return "Attribute(%r, %r)" % (self._name, self._doc)
365 return "Attribute(%r, %r)" % (self._name, self._doc)
367
366
368
367
369 class IndexDescriptor(Descriptor):
368 class IndexDescriptor(Descriptor):
370 """
369 """
371 An ``IndexDescriptor`` describes an "attribute" of an object that is fetched
370 An ``IndexDescriptor`` describes an "attribute" of an object that is fetched
372 via ``__getitem__``.
371 via ``__getitem__``.
373 """
372 """
374 __slots__ = ("_index",)
373 __slots__ = ("_index",)
375
374
376 def __init__(self, index):
375 def __init__(self, index):
377 self._index = index
376 self._index = index
378
377
379 def key(self):
378 def key(self):
380 return self._index
379 return self._index
381
380
382 def attrtype(self, obj):
381 def attrtype(self, obj):
383 return "item"
382 return "item"
384
383
385 def valuetype(self, obj):
384 def valuetype(self, obj):
386 return type(obj[self._index])
385 return type(obj[self._index])
387
386
388 def value(self, obj):
387 def value(self, obj):
389 return obj[self._index]
388 return obj[self._index]
390
389
391 def __repr__(self):
390 def __repr__(self):
392 return "Index(%r)" % self._index
391 return "Index(%r)" % self._index
393
392
394
393
395 class MethodDescriptor(Descriptor):
394 class MethodDescriptor(Descriptor):
396 """
395 """
397 A ``MethodDescriptor`` describes a method of an object that can be called
396 A ``MethodDescriptor`` describes a method of an object that can be called
398 without argument. Note that this method shouldn't change the object.
397 without argument. Note that this method shouldn't change the object.
399 """
398 """
400 __slots__ = ("_name", "_doc")
399 __slots__ = ("_name", "_doc")
401
400
402 def __init__(self, name, doc=None):
401 def __init__(self, name, doc=None):
403 self._name = name
402 self._name = name
404 self._doc = doc
403 self._doc = doc
405
404
406 def key(self):
405 def key(self):
407 return self._name
406 return self._name
408
407
409 def doc(self, obj):
408 def doc(self, obj):
410 if self._doc is None:
409 if self._doc is None:
411 return getattr(obj, self._name).__doc__
410 return getattr(obj, self._name).__doc__
412 return self._doc
411 return self._doc
413
412
414 def attrtype(self, obj):
413 def attrtype(self, obj):
415 return "method"
414 return "method"
416
415
417 def valuetype(self, obj):
416 def valuetype(self, obj):
418 return type(self.value(obj))
417 return type(self.value(obj))
419
418
420 def value(self, obj):
419 def value(self, obj):
421 return getattr(obj, self._name)()
420 return getattr(obj, self._name)()
422
421
423 def __repr__(self):
422 def __repr__(self):
424 if self._doc is None:
423 if self._doc is None:
425 return "Method(%r)" % self._name
424 return "Method(%r)" % self._name
426 else:
425 else:
427 return "Method(%r, %r)" % (self._name, self._doc)
426 return "Method(%r, %r)" % (self._name, self._doc)
428
427
429
428
430 class IterAttributeDescriptor(Descriptor):
429 class IterAttributeDescriptor(Descriptor):
431 """
430 """
432 An ``IterAttributeDescriptor`` works like an ``AttributeDescriptor`` but
431 An ``IterAttributeDescriptor`` works like an ``AttributeDescriptor`` but
433 doesn't return an attribute values (because this value might be e.g. a large
432 doesn't return an attribute values (because this value might be e.g. a large
434 list).
433 list).
435 """
434 """
436 __slots__ = ("_name", "_doc")
435 __slots__ = ("_name", "_doc")
437
436
438 def __init__(self, name, doc=None):
437 def __init__(self, name, doc=None):
439 self._name = name
438 self._name = name
440 self._doc = doc
439 self._doc = doc
441
440
442 def key(self):
441 def key(self):
443 return self._name
442 return self._name
444
443
445 def doc(self, obj):
444 def doc(self, obj):
446 return self._doc
445 return self._doc
447
446
448 def attrtype(self, obj):
447 def attrtype(self, obj):
449 return "iter"
448 return "iter"
450
449
451 def valuetype(self, obj):
450 def valuetype(self, obj):
452 return noitem
451 return noitem
453
452
454 def value(self, obj):
453 def value(self, obj):
455 return noitem
454 return noitem
456
455
457 def iter(self, obj):
456 def iter(self, obj):
458 return xiter(getattr(obj, self._name))
457 return xiter(getattr(obj, self._name))
459
458
460 def __repr__(self):
459 def __repr__(self):
461 if self._doc is None:
460 if self._doc is None:
462 return "IterAttribute(%r)" % self._name
461 return "IterAttribute(%r)" % self._name
463 else:
462 else:
464 return "IterAttribute(%r, %r)" % (self._name, self._doc)
463 return "IterAttribute(%r, %r)" % (self._name, self._doc)
465
464
466
465
467 class IterMethodDescriptor(Descriptor):
466 class IterMethodDescriptor(Descriptor):
468 """
467 """
469 An ``IterMethodDescriptor`` works like an ``MethodDescriptor`` but doesn't
468 An ``IterMethodDescriptor`` works like an ``MethodDescriptor`` but doesn't
470 return an attribute values (because this value might be e.g. a large list).
469 return an attribute values (because this value might be e.g. a large list).
471 """
470 """
472 __slots__ = ("_name", "_doc")
471 __slots__ = ("_name", "_doc")
473
472
474 def __init__(self, name, doc=None):
473 def __init__(self, name, doc=None):
475 self._name = name
474 self._name = name
476 self._doc = doc
475 self._doc = doc
477
476
478 def key(self):
477 def key(self):
479 return self._name
478 return self._name
480
479
481 def doc(self, obj):
480 def doc(self, obj):
482 if self._doc is None:
481 if self._doc is None:
483 return getattr(obj, self._name).__doc__
482 return getattr(obj, self._name).__doc__
484 return self._doc
483 return self._doc
485
484
486 def attrtype(self, obj):
485 def attrtype(self, obj):
487 return "itermethod"
486 return "itermethod"
488
487
489 def valuetype(self, obj):
488 def valuetype(self, obj):
490 return noitem
489 return noitem
491
490
492 def value(self, obj):
491 def value(self, obj):
493 return noitem
492 return noitem
494
493
495 def iter(self, obj):
494 def iter(self, obj):
496 return xiter(getattr(obj, self._name)())
495 return xiter(getattr(obj, self._name)())
497
496
498 def __repr__(self):
497 def __repr__(self):
499 if self._doc is None:
498 if self._doc is None:
500 return "IterMethod(%r)" % self._name
499 return "IterMethod(%r)" % self._name
501 else:
500 else:
502 return "IterMethod(%r, %r)" % (self._name, self._doc)
501 return "IterMethod(%r, %r)" % (self._name, self._doc)
503
502
504
503
505 class FunctionDescriptor(Descriptor):
504 class FunctionDescriptor(Descriptor):
506 """
505 """
507 A ``FunctionDescriptor`` turns a function into a descriptor. The function
506 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.
507 will be called with the object to get the type and value of the attribute.
509 """
508 """
510 __slots__ = ("_function", "_name", "_doc")
509 __slots__ = ("_function", "_name", "_doc")
511
510
512 def __init__(self, function, name=None, doc=None):
511 def __init__(self, function, name=None, doc=None):
513 self._function = function
512 self._function = function
514 self._name = name
513 self._name = name
515 self._doc = doc
514 self._doc = doc
516
515
517 def key(self):
516 def key(self):
518 return self._function
517 return self._function
519
518
520 def name(self):
519 def name(self):
521 if self._name is not None:
520 if self._name is not None:
522 return self._name
521 return self._name
523 return getattr(self._function, "__xname__", self._function.__name__)
522 return getattr(self._function, "__xname__", self._function.__name__)
524
523
525 def doc(self, obj):
524 def doc(self, obj):
526 if self._doc is None:
525 if self._doc is None:
527 return self._function.__doc__
526 return self._function.__doc__
528 return self._doc
527 return self._doc
529
528
530 def attrtype(self, obj):
529 def attrtype(self, obj):
531 return "function"
530 return "function"
532
531
533 def valuetype(self, obj):
532 def valuetype(self, obj):
534 return type(self._function(obj))
533 return type(self._function(obj))
535
534
536 def value(self, obj):
535 def value(self, obj):
537 return self._function(obj)
536 return self._function(obj)
538
537
539 def __repr__(self):
538 def __repr__(self):
540 if self._doc is None:
539 if self._doc is None:
541 return "Function(%r)" % self._name
540 return "Function(%r)" % self._name
542 else:
541 else:
543 return "Function(%r, %r)" % (self._name, self._doc)
542 return "Function(%r, %r)" % (self._name, self._doc)
544
543
545
544
546 class Table(object):
545 class Table(object):
547 """
546 """
548 A ``Table`` is an object that produces items (just like a normal Python
547 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
548 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
549 expression. The displayhook will open the default browser for such an object
551 (instead of simply printing the ``repr()`` result).
550 (instead of simply printing the ``repr()`` result).
552 """
551 """
553
552
554 # We want to support ``foo`` and ``foo()`` in pipeline expression:
553 # We want to support ``foo`` and ``foo()`` in pipeline expression:
555 # So we implement the required operators (``|`` and ``+``) in the metaclass,
554 # So we implement the required operators (``|`` and ``+``) in the metaclass,
556 # instantiate the class and forward the operator to the instance
555 # instantiate the class and forward the operator to the instance
557 class __metaclass__(type):
556 class __metaclass__(type):
558 def __iter__(self):
557 def __iter__(self):
559 return iter(self())
558 return iter(self())
560
559
561 def __or__(self, other):
560 def __or__(self, other):
562 return self() | other
561 return self() | other
563
562
564 def __add__(self, other):
563 def __add__(self, other):
565 return self() + other
564 return self() + other
566
565
567 def __radd__(self, other):
566 def __radd__(self, other):
568 return other + self()
567 return other + self()
569
568
570 def __getitem__(self, index):
569 def __getitem__(self, index):
571 return self()[index]
570 return self()[index]
572
571
573 def __getitem__(self, index):
572 def __getitem__(self, index):
574 return item(self, index)
573 return item(self, index)
575
574
576 def __contains__(self, item):
575 def __contains__(self, item):
577 for haveitem in self:
576 for haveitem in self:
578 if item == haveitem:
577 if item == haveitem:
579 return True
578 return True
580 return False
579 return False
581
580
582 def __or__(self, other):
581 def __or__(self, other):
583 # autoinstantiate right hand side
582 # autoinstantiate right hand side
584 if isinstance(other, type) and issubclass(other, (Table, Display)):
583 if isinstance(other, type) and issubclass(other, (Table, Display)):
585 other = other()
584 other = other()
586 # treat simple strings and functions as ``ieval`` instances
585 # treat simple strings and functions as ``ieval`` instances
587 elif not isinstance(other, Display) and not isinstance(other, Table):
586 elif not isinstance(other, Display) and not isinstance(other, Table):
588 other = ieval(other)
587 other = ieval(other)
589 # forward operations to the right hand side
588 # forward operations to the right hand side
590 return other.__ror__(self)
589 return other.__ror__(self)
591
590
592 def __add__(self, other):
591 def __add__(self, other):
593 # autoinstantiate right hand side
592 # autoinstantiate right hand side
594 if isinstance(other, type) and issubclass(other, Table):
593 if isinstance(other, type) and issubclass(other, Table):
595 other = other()
594 other = other()
596 return ichain(self, other)
595 return ichain(self, other)
597
596
598 def __radd__(self, other):
597 def __radd__(self, other):
599 # autoinstantiate left hand side
598 # autoinstantiate left hand side
600 if isinstance(other, type) and issubclass(other, Table):
599 if isinstance(other, type) and issubclass(other, Table):
601 other = other()
600 other = other()
602 return ichain(other, self)
601 return ichain(other, self)
603
602
604
603
605 class Pipe(Table):
604 class Pipe(Table):
606 """
605 """
607 A ``Pipe`` is an object that can be used in a pipeline expression. It
606 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
607 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
608 a ``Pipe`` object can't be used as the first object in a pipeline
610 expression, as it doesn't produces items itself.
609 expression, as it doesn't produces items itself.
611 """
610 """
612 class __metaclass__(Table.__metaclass__):
611 class __metaclass__(Table.__metaclass__):
613 def __ror__(self, input):
612 def __ror__(self, input):
614 return input | self()
613 return input | self()
615
614
616 def __ror__(self, input):
615 def __ror__(self, input):
617 # autoinstantiate left hand side
616 # autoinstantiate left hand side
618 if isinstance(input, type) and issubclass(input, Table):
617 if isinstance(input, type) and issubclass(input, Table):
619 input = input()
618 input = input()
620 self.input = input
619 self.input = input
621 return self
620 return self
622
621
623
622
624 def xrepr(item, mode="default"):
623 def xrepr(item, mode="default"):
625 """
624 """
626 Generic function that adds color output and different display modes to ``repr``.
625 Generic function that adds color output and different display modes to ``repr``.
627
626
628 The result of an ``xrepr`` call is iterable and consists of ``(style, string)``
627 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
628 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
629 ``astring`` module. To reconfigure the output the first yielded tuple can be
631 a ``(aligment, full)`` tuple instead of a ``(style, string)`` tuple.
630 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
631 ``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
632 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
633 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
634 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
635 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).
636 (i.e. a nested list, tuple or dictionary) ``False`` would be used).
638 The default is full output.
637 The default is full output.
639
638
640 There are four different possible values for ``mode`` depending on where
639 There are four different possible values for ``mode`` depending on where
641 the ``Display`` object will display ``item``:
640 the ``Display`` object will display ``item``:
642
641
643 ``"header"``
642 ``"header"``
644 ``item`` will be displayed in a header line (this is used by ``ibrowse``).
643 ``item`` will be displayed in a header line (this is used by ``ibrowse``).
645
644
646 ``"footer"``
645 ``"footer"``
647 ``item`` will be displayed in a footer line (this is used by ``ibrowse``).
646 ``item`` will be displayed in a footer line (this is used by ``ibrowse``).
648
647
649 ``"cell"``
648 ``"cell"``
650 ``item`` will be displayed in a table cell/list.
649 ``item`` will be displayed in a table cell/list.
651
650
652 ``"default"``
651 ``"default"``
653 default mode. If an ``xrepr`` implementation recursively outputs objects,
652 default mode. If an ``xrepr`` implementation recursively outputs objects,
654 ``"default"`` must be passed in the recursive calls to ``xrepr``.
653 ``"default"`` must be passed in the recursive calls to ``xrepr``.
655
654
656 If no implementation is registered for ``item``, ``xrepr`` will try the
655 If no implementation is registered for ``item``, ``xrepr`` will try the
657 ``__xrepr__`` method on ``item``. If ``item`` doesn't have an ``__xrepr__``
656 ``__xrepr__`` method on ``item``. If ``item`` doesn't have an ``__xrepr__``
658 method it falls back to ``repr``/``__repr__`` for all modes.
657 method it falls back to ``repr``/``__repr__`` for all modes.
659 """
658 """
660 try:
659 try:
661 func = item.__xrepr__
660 func = item.__xrepr__
662 except AttributeError:
661 except AttributeError:
663 yield (astyle.style_default, repr(item))
662 yield (astyle.style_default, repr(item))
664 else:
663 else:
665 try:
664 try:
666 for x in func(mode):
665 for x in func(mode):
667 yield x
666 yield x
668 except (KeyboardInterrupt, SystemExit):
667 except (KeyboardInterrupt, SystemExit):
669 raise
668 raise
670 except Exception:
669 except Exception:
671 yield (astyle.style_default, repr(item))
670 yield (astyle.style_default, repr(item))
672 xrepr = simplegeneric.generic(xrepr)
671 xrepr = simplegeneric.generic(xrepr)
673
672
674
673
675 def xrepr_none(self, mode="default"):
674 def xrepr_none(self, mode="default"):
676 yield (astyle.style_type_none, repr(self))
675 yield (astyle.style_type_none, repr(self))
677 xrepr.when_object(None)(xrepr_none)
676 xrepr.when_object(None)(xrepr_none)
678
677
679
678
680 def xrepr_noitem(self, mode="default"):
679 def xrepr_noitem(self, mode="default"):
681 yield (2, True)
680 yield (2, True)
682 yield (astyle.style_nodata, "<?>")
681 yield (astyle.style_nodata, "<?>")
683 xrepr.when_object(noitem)(xrepr_noitem)
682 xrepr.when_object(noitem)(xrepr_noitem)
684
683
685
684
686 def xrepr_bool(self, mode="default"):
685 def xrepr_bool(self, mode="default"):
687 yield (astyle.style_type_bool, repr(self))
686 yield (astyle.style_type_bool, repr(self))
688 xrepr.when_type(bool)(xrepr_bool)
687 xrepr.when_type(bool)(xrepr_bool)
689
688
690
689
691 def xrepr_str(self, mode="default"):
690 def xrepr_str(self, mode="default"):
692 if mode == "cell":
691 if mode == "cell":
693 yield (astyle.style_default, repr(self.expandtabs(tab))[1:-1])
692 yield (astyle.style_default, repr(self.expandtabs(tab))[1:-1])
694 else:
693 else:
695 yield (astyle.style_default, repr(self))
694 yield (astyle.style_default, repr(self))
696 xrepr.when_type(str)(xrepr_str)
695 xrepr.when_type(str)(xrepr_str)
697
696
698
697
699 def xrepr_unicode(self, mode="default"):
698 def xrepr_unicode(self, mode="default"):
700 if mode == "cell":
699 if mode == "cell":
701 yield (astyle.style_default, repr(self.expandtabs(tab))[2:-1])
700 yield (astyle.style_default, repr(self.expandtabs(tab))[2:-1])
702 else:
701 else:
703 yield (astyle.style_default, repr(self))
702 yield (astyle.style_default, repr(self))
704 xrepr.when_type(unicode)(xrepr_unicode)
703 xrepr.when_type(unicode)(xrepr_unicode)
705
704
706
705
707 def xrepr_number(self, mode="default"):
706 def xrepr_number(self, mode="default"):
708 yield (1, True)
707 yield (1, True)
709 yield (astyle.style_type_number, repr(self))
708 yield (astyle.style_type_number, repr(self))
710 xrepr.when_type(int)(xrepr_number)
709 xrepr.when_type(int)(xrepr_number)
711 xrepr.when_type(long)(xrepr_number)
710 xrepr.when_type(long)(xrepr_number)
712 xrepr.when_type(float)(xrepr_number)
711 xrepr.when_type(float)(xrepr_number)
713
712
714
713
715 def xrepr_complex(self, mode="default"):
714 def xrepr_complex(self, mode="default"):
716 yield (astyle.style_type_number, repr(self))
715 yield (astyle.style_type_number, repr(self))
717 xrepr.when_type(complex)(xrepr_number)
716 xrepr.when_type(complex)(xrepr_number)
718
717
719
718
720 def xrepr_datetime(self, mode="default"):
719 def xrepr_datetime(self, mode="default"):
721 if mode == "cell":
720 if mode == "cell":
722 # Don't use strftime() here, as this requires year >= 1900
721 # Don't use strftime() here, as this requires year >= 1900
723 yield (astyle.style_type_datetime,
722 yield (astyle.style_type_datetime,
724 "%04d-%02d-%02d %02d:%02d:%02d.%06d" % \
723 "%04d-%02d-%02d %02d:%02d:%02d.%06d" % \
725 (self.year, self.month, self.day,
724 (self.year, self.month, self.day,
726 self.hour, self.minute, self.second,
725 self.hour, self.minute, self.second,
727 self.microsecond),
726 self.microsecond),
728 )
727 )
729 else:
728 else:
730 yield (astyle.style_type_datetime, repr(self))
729 yield (astyle.style_type_datetime, repr(self))
731 xrepr.when_type(datetime.datetime)(xrepr_datetime)
730 xrepr.when_type(datetime.datetime)(xrepr_datetime)
732
731
733
732
734 def xrepr_date(self, mode="default"):
733 def xrepr_date(self, mode="default"):
735 if mode == "cell":
734 if mode == "cell":
736 yield (astyle.style_type_datetime,
735 yield (astyle.style_type_datetime,
737 "%04d-%02d-%02d" % (self.year, self.month, self.day))
736 "%04d-%02d-%02d" % (self.year, self.month, self.day))
738 else:
737 else:
739 yield (astyle.style_type_datetime, repr(self))
738 yield (astyle.style_type_datetime, repr(self))
740 xrepr.when_type(datetime.date)(xrepr_date)
739 xrepr.when_type(datetime.date)(xrepr_date)
741
740
742
741
743 def xrepr_time(self, mode="default"):
742 def xrepr_time(self, mode="default"):
744 if mode == "cell":
743 if mode == "cell":
745 yield (astyle.style_type_datetime,
744 yield (astyle.style_type_datetime,
746 "%02d:%02d:%02d.%06d" % \
745 "%02d:%02d:%02d.%06d" % \
747 (self.hour, self.minute, self.second, self.microsecond))
746 (self.hour, self.minute, self.second, self.microsecond))
748 else:
747 else:
749 yield (astyle.style_type_datetime, repr(self))
748 yield (astyle.style_type_datetime, repr(self))
750 xrepr.when_type(datetime.time)(xrepr_time)
749 xrepr.when_type(datetime.time)(xrepr_time)
751
750
752
751
753 def xrepr_timedelta(self, mode="default"):
752 def xrepr_timedelta(self, mode="default"):
754 yield (astyle.style_type_datetime, repr(self))
753 yield (astyle.style_type_datetime, repr(self))
755 xrepr.when_type(datetime.timedelta)(xrepr_timedelta)
754 xrepr.when_type(datetime.timedelta)(xrepr_timedelta)
756
755
757
756
758 def xrepr_type(self, mode="default"):
757 def xrepr_type(self, mode="default"):
759 if self.__module__ == "__builtin__":
758 if self.__module__ == "__builtin__":
760 yield (astyle.style_type_type, self.__name__)
759 yield (astyle.style_type_type, self.__name__)
761 else:
760 else:
762 yield (astyle.style_type_type, "%s.%s" % (self.__module__, self.__name__))
761 yield (astyle.style_type_type, "%s.%s" % (self.__module__, self.__name__))
763 xrepr.when_type(type)(xrepr_type)
762 xrepr.when_type(type)(xrepr_type)
764
763
765
764
766 def xrepr_exception(self, mode="default"):
765 def xrepr_exception(self, mode="default"):
767 if self.__class__.__module__ == "exceptions":
766 if self.__class__.__module__ == "exceptions":
768 classname = self.__class__.__name__
767 classname = self.__class__.__name__
769 else:
768 else:
770 classname = "%s.%s" % \
769 classname = "%s.%s" % \
771 (self.__class__.__module__, self.__class__.__name__)
770 (self.__class__.__module__, self.__class__.__name__)
772 if mode == "header" or mode == "footer":
771 if mode == "header" or mode == "footer":
773 yield (astyle.style_error, "%s: %s" % (classname, self))
772 yield (astyle.style_error, "%s: %s" % (classname, self))
774 else:
773 else:
775 yield (astyle.style_error, classname)
774 yield (astyle.style_error, classname)
776 xrepr.when_type(Exception)(xrepr_exception)
775 xrepr.when_type(Exception)(xrepr_exception)
777
776
778
777
779 def xrepr_listtuple(self, mode="default"):
778 def xrepr_listtuple(self, mode="default"):
780 if mode == "header" or mode == "footer":
779 if mode == "header" or mode == "footer":
781 if self.__class__.__module__ == "__builtin__":
780 if self.__class__.__module__ == "__builtin__":
782 classname = self.__class__.__name__
781 classname = self.__class__.__name__
783 else:
782 else:
784 classname = "%s.%s" % \
783 classname = "%s.%s" % \
785 (self.__class__.__module__,self.__class__.__name__)
784 (self.__class__.__module__,self.__class__.__name__)
786 yield (astyle.style_default,
785 yield (astyle.style_default,
787 "<%s object with %d items at 0x%x>" % \
786 "<%s object with %d items at 0x%x>" % \
788 (classname, len(self), id(self)))
787 (classname, len(self), id(self)))
789 else:
788 else:
790 yield (-1, False)
789 yield (-1, False)
791 if isinstance(self, list):
790 if isinstance(self, list):
792 yield (astyle.style_default, "[")
791 yield (astyle.style_default, "[")
793 end = "]"
792 end = "]"
794 else:
793 else:
795 yield (astyle.style_default, "(")
794 yield (astyle.style_default, "(")
796 end = ")"
795 end = ")"
797 for (i, subself) in enumerate(self):
796 for (i, subself) in enumerate(self):
798 if i:
797 if i:
799 yield (astyle.style_default, ", ")
798 yield (astyle.style_default, ", ")
800 for part in xrepr(subself, "default"):
799 for part in xrepr(subself, "default"):
801 yield part
800 yield part
802 yield (astyle.style_default, end)
801 yield (astyle.style_default, end)
803 xrepr.when_type(list)(xrepr_listtuple)
802 xrepr.when_type(list)(xrepr_listtuple)
804 xrepr.when_type(tuple)(xrepr_listtuple)
803 xrepr.when_type(tuple)(xrepr_listtuple)
805
804
806
805
807 def xrepr_dict(self, mode="default"):
806 def xrepr_dict(self, mode="default"):
808 if mode == "header" or mode == "footer":
807 if mode == "header" or mode == "footer":
809 if self.__class__.__module__ == "__builtin__":
808 if self.__class__.__module__ == "__builtin__":
810 classname = self.__class__.__name__
809 classname = self.__class__.__name__
811 else:
810 else:
812 classname = "%s.%s" % \
811 classname = "%s.%s" % \
813 (self.__class__.__module__,self.__class__.__name__)
812 (self.__class__.__module__,self.__class__.__name__)
814 yield (astyle.style_default,
813 yield (astyle.style_default,
815 "<%s object with %d items at 0x%x>" % \
814 "<%s object with %d items at 0x%x>" % \
816 (classname, len(self), id(self)))
815 (classname, len(self), id(self)))
817 else:
816 else:
818 yield (-1, False)
817 yield (-1, False)
819 if isinstance(self, dict):
818 if isinstance(self, dict):
820 yield (astyle.style_default, "{")
819 yield (astyle.style_default, "{")
821 end = "}"
820 end = "}"
822 else:
821 else:
823 yield (astyle.style_default, "dictproxy((")
822 yield (astyle.style_default, "dictproxy((")
824 end = "})"
823 end = "})"
825 for (i, (key, value)) in enumerate(self.iteritems()):
824 for (i, (key, value)) in enumerate(self.iteritems()):
826 if i:
825 if i:
827 yield (astyle.style_default, ", ")
826 yield (astyle.style_default, ", ")
828 for part in xrepr(key, "default"):
827 for part in xrepr(key, "default"):
829 yield part
828 yield part
830 yield (astyle.style_default, ": ")
829 yield (astyle.style_default, ": ")
831 for part in xrepr(value, "default"):
830 for part in xrepr(value, "default"):
832 yield part
831 yield part
833 yield (astyle.style_default, end)
832 yield (astyle.style_default, end)
834 xrepr.when_type(dict)(xrepr_dict)
833 xrepr.when_type(dict)(xrepr_dict)
835 xrepr.when_type(types.DictProxyType)(xrepr_dict)
834 xrepr.when_type(types.DictProxyType)(xrepr_dict)
836
835
837
836
838 def upgradexattr(attr):
837 def upgradexattr(attr):
839 """
838 """
840 Convert an attribute descriptor string to a real descriptor object.
839 Convert an attribute descriptor string to a real descriptor object.
841
840
842 If attr already is a descriptor object return if unmodified. A
841 If attr already is a descriptor object return if unmodified. A
843 ``SelfDescriptor`` will be returned if ``attr`` is ``None``. ``"foo"``
842 ``SelfDescriptor`` will be returned if ``attr`` is ``None``. ``"foo"``
844 returns an ``AttributeDescriptor`` for the attribute named ``"foo"``.
843 returns an ``AttributeDescriptor`` for the attribute named ``"foo"``.
845 ``"foo()"`` returns a ``MethodDescriptor`` for the method named ``"foo"``.
844 ``"foo()"`` returns a ``MethodDescriptor`` for the method named ``"foo"``.
846 ``"-foo"`` will return an ``IterAttributeDescriptor`` for the attribute
845 ``"-foo"`` will return an ``IterAttributeDescriptor`` for the attribute
847 named ``"foo"`` and ``"-foo()"`` will return an ``IterMethodDescriptor``
846 named ``"foo"`` and ``"-foo()"`` will return an ``IterMethodDescriptor``
848 for the method named ``"foo"``. Furthermore integer will return the appropriate
847 for the method named ``"foo"``. Furthermore integer will return the appropriate
849 ``IndexDescriptor`` and callables will return a ``FunctionDescriptor``.
848 ``IndexDescriptor`` and callables will return a ``FunctionDescriptor``.
850 """
849 """
851 if attr is None:
850 if attr is None:
852 return selfdescriptor
851 return selfdescriptor
853 elif isinstance(attr, Descriptor):
852 elif isinstance(attr, Descriptor):
854 return attr
853 return attr
855 elif isinstance(attr, str):
854 elif isinstance(attr, str):
856 if attr.endswith("()"):
855 if attr.endswith("()"):
857 if attr.startswith("-"):
856 if attr.startswith("-"):
858 return IterMethodDescriptor(attr[1:-2])
857 return IterMethodDescriptor(attr[1:-2])
859 else:
858 else:
860 return MethodDescriptor(attr[:-2])
859 return MethodDescriptor(attr[:-2])
861 else:
860 else:
862 if attr.startswith("-"):
861 if attr.startswith("-"):
863 return IterAttributeDescriptor(attr[1:])
862 return IterAttributeDescriptor(attr[1:])
864 else:
863 else:
865 return AttributeDescriptor(attr)
864 return AttributeDescriptor(attr)
866 elif isinstance(attr, (int, long)):
865 elif isinstance(attr, (int, long)):
867 return IndexDescriptor(attr)
866 return IndexDescriptor(attr)
868 elif callable(attr):
867 elif callable(attr):
869 return FunctionDescriptor(attr)
868 return FunctionDescriptor(attr)
870 else:
869 else:
871 raise TypeError("can't handle descriptor %r" % attr)
870 raise TypeError("can't handle descriptor %r" % attr)
872
871
873
872
874 def xattrs(item, mode="default"):
873 def xattrs(item, mode="default"):
875 """
874 """
876 Generic function that returns an iterable of attribute descriptors
875 Generic function that returns an iterable of attribute descriptors
877 to be used for displaying the attributes ob the object ``item`` in display
876 to be used for displaying the attributes ob the object ``item`` in display
878 mode ``mode``.
877 mode ``mode``.
879
878
880 There are two possible modes:
879 There are two possible modes:
881
880
882 ``"detail"``
881 ``"detail"``
883 The ``Display`` object wants to display a detailed list of the object
882 The ``Display`` object wants to display a detailed list of the object
884 attributes.
883 attributes.
885
884
886 ``"default"``
885 ``"default"``
887 The ``Display`` object wants to display the object in a list view.
886 The ``Display`` object wants to display the object in a list view.
888
887
889 If no implementation is registered for the object ``item`` ``xattrs`` falls
888 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
889 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,)``
890 exist either, ``dir(item)`` is used for ``"detail"`` mode and ``(None,)``
892 for ``"default"`` mode.
891 for ``"default"`` mode.
893
892
894 The implementation must yield attribute descriptors (see the class
893 The implementation must yield attribute descriptors (see the class
895 ``Descriptor`` for more info). The ``__xattrs__`` method may also return
894 ``Descriptor`` for more info). The ``__xattrs__`` method may also return
896 attribute descriptor strings (and ``None``) which will be converted to real
895 attribute descriptor strings (and ``None``) which will be converted to real
897 descriptors by ``upgradexattr()``.
896 descriptors by ``upgradexattr()``.
898 """
897 """
899 try:
898 try:
900 func = item.__xattrs__
899 func = item.__xattrs__
901 except AttributeError:
900 except AttributeError:
902 if mode == "detail":
901 if mode == "detail":
903 for attrname in dir(item):
902 for attrname in dir(item):
904 yield AttributeDescriptor(attrname)
903 yield AttributeDescriptor(attrname)
905 else:
904 else:
906 yield selfdescriptor
905 yield selfdescriptor
907 else:
906 else:
908 for attr in func(mode):
907 for attr in func(mode):
909 yield upgradexattr(attr)
908 yield upgradexattr(attr)
910 xattrs = simplegeneric.generic(xattrs)
909 xattrs = simplegeneric.generic(xattrs)
911
910
912
911
913 def xattrs_complex(self, mode="default"):
912 def xattrs_complex(self, mode="default"):
914 if mode == "detail":
913 if mode == "detail":
915 return (AttributeDescriptor("real"), AttributeDescriptor("imag"))
914 return (AttributeDescriptor("real"), AttributeDescriptor("imag"))
916 return (selfdescriptor,)
915 return (selfdescriptor,)
917 xattrs.when_type(complex)(xattrs_complex)
916 xattrs.when_type(complex)(xattrs_complex)
918
917
919
918
920 def _isdict(item):
919 def _isdict(item):
921 try:
920 try:
922 itermeth = item.__class__.__iter__
921 itermeth = item.__class__.__iter__
923 except (AttributeError, TypeError):
922 except (AttributeError, TypeError):
924 return False
923 return False
925 return itermeth is dict.__iter__ or itermeth is types.DictProxyType.__iter__
924 return itermeth is dict.__iter__ or itermeth is types.DictProxyType.__iter__
926
925
927
926
928 def _isstr(item):
927 def _isstr(item):
929 if not isinstance(item, basestring):
928 if not isinstance(item, basestring):
930 return False
929 return False
931 try:
930 try:
932 itermeth = item.__class__.__iter__
931 itermeth = item.__class__.__iter__
933 except AttributeError:
932 except AttributeError:
934 return True
933 return True
935 return False # ``__iter__`` has been redefined
934 return False # ``__iter__`` has been redefined
936
935
937
936
938 def xiter(item):
937 def xiter(item):
939 """
938 """
940 Generic function that implements iteration for pipeline expression. If no
939 Generic function that implements iteration for pipeline expression. If no
941 implementation is registered for ``item`` ``xiter`` falls back to ``iter``.
940 implementation is registered for ``item`` ``xiter`` falls back to ``iter``.
942 """
941 """
943 try:
942 try:
944 func = item.__xiter__
943 func = item.__xiter__
945 except AttributeError:
944 except AttributeError:
946 if _isdict(item):
945 if _isdict(item):
947 def items(item):
946 def items(item):
948 fields = ("key", "value")
947 fields = ("key", "value")
949 for (key, value) in item.iteritems():
948 for (key, value) in item.iteritems():
950 yield Fields(fields, key=key, value=value)
949 yield Fields(fields, key=key, value=value)
951 return items(item)
950 return items(item)
952 elif isinstance(item, new.module):
951 elif isinstance(item, new.module):
953 def items(item):
952 def items(item):
954 fields = ("key", "value")
953 fields = ("key", "value")
955 for key in sorted(item.__dict__):
954 for key in sorted(item.__dict__):
956 yield Fields(fields, key=key, value=getattr(item, key))
955 yield Fields(fields, key=key, value=getattr(item, key))
957 return items(item)
956 return items(item)
958 elif _isstr(item):
957 elif _isstr(item):
959 if not item:
958 if not item:
960 raise ValueError("can't enter empty string")
959 raise ValueError("can't enter empty string")
961 lines = item.splitlines()
960 lines = item.splitlines()
962 if len(lines) == 1:
961 if len(lines) == 1:
963 def iterone(item):
962 def iterone(item):
964 yield item
963 yield item
965 return iterone(item)
964 return iterone(item)
966 else:
965 else:
967 return iter(lines)
966 return iter(lines)
968 return iter(item)
967 return iter(item)
969 else:
968 else:
970 return iter(func()) # iter() just to be safe
969 return iter(func()) # iter() just to be safe
971 xiter = simplegeneric.generic(xiter)
970 xiter = simplegeneric.generic(xiter)
972
971
973
972
974 class ichain(Pipe):
973 class ichain(Pipe):
975 """
974 """
976 Chains multiple ``Table``s into one.
975 Chains multiple ``Table``s into one.
977 """
976 """
978
977
979 def __init__(self, *iters):
978 def __init__(self, *iters):
980 self.iters = iters
979 self.iters = iters
981
980
982 def __iter__(self):
981 def __iter__(self):
983 return itertools.chain(*self.iters)
982 return itertools.chain(*self.iters)
984
983
985 def __xrepr__(self, mode="default"):
984 def __xrepr__(self, mode="default"):
986 if mode == "header" or mode == "footer":
985 if mode == "header" or mode == "footer":
987 for (i, item) in enumerate(self.iters):
986 for (i, item) in enumerate(self.iters):
988 if i:
987 if i:
989 yield (astyle.style_default, "+")
988 yield (astyle.style_default, "+")
990 if isinstance(item, Pipe):
989 if isinstance(item, Pipe):
991 yield (astyle.style_default, "(")
990 yield (astyle.style_default, "(")
992 for part in xrepr(item, mode):
991 for part in xrepr(item, mode):
993 yield part
992 yield part
994 if isinstance(item, Pipe):
993 if isinstance(item, Pipe):
995 yield (astyle.style_default, ")")
994 yield (astyle.style_default, ")")
996 else:
995 else:
997 yield (astyle.style_default, repr(self))
996 yield (astyle.style_default, repr(self))
998
997
999 def __repr__(self):
998 def __repr__(self):
1000 args = ", ".join([repr(it) for it in self.iters])
999 args = ", ".join([repr(it) for it in self.iters])
1001 return "%s.%s(%s)" % \
1000 return "%s.%s(%s)" % \
1002 (self.__class__.__module__, self.__class__.__name__, args)
1001 (self.__class__.__module__, self.__class__.__name__, args)
1003
1002
1004
1003
1005 class ifile(path.path):
1004 class ifile(path.path):
1006 """
1005 """
1007 file (or directory) object.
1006 file (or directory) object.
1008 """
1007 """
1009
1008
1010 def getmode(self):
1009 def getmode(self):
1011 return self.stat().st_mode
1010 return self.stat().st_mode
1012 mode = property(getmode, None, None, "Access mode")
1011 mode = property(getmode, None, None, "Access mode")
1013
1012
1014 def gettype(self):
1013 def gettype(self):
1015 data = [
1014 data = [
1016 (stat.S_ISREG, "file"),
1015 (stat.S_ISREG, "file"),
1017 (stat.S_ISDIR, "dir"),
1016 (stat.S_ISDIR, "dir"),
1018 (stat.S_ISCHR, "chardev"),
1017 (stat.S_ISCHR, "chardev"),
1019 (stat.S_ISBLK, "blockdev"),
1018 (stat.S_ISBLK, "blockdev"),
1020 (stat.S_ISFIFO, "fifo"),
1019 (stat.S_ISFIFO, "fifo"),
1021 (stat.S_ISLNK, "symlink"),
1020 (stat.S_ISLNK, "symlink"),
1022 (stat.S_ISSOCK,"socket"),
1021 (stat.S_ISSOCK,"socket"),
1023 ]
1022 ]
1024 lstat = self.lstat()
1023 lstat = self.lstat()
1025 if lstat is not None:
1024 if lstat is not None:
1026 types = set([text for (func, text) in data if func(lstat.st_mode)])
1025 types = set([text for (func, text) in data if func(lstat.st_mode)])
1027 else:
1026 else:
1028 types = set()
1027 types = set()
1029 m = self.mode
1028 m = self.mode
1030 types.update([text for (func, text) in data if func(m)])
1029 types.update([text for (func, text) in data if func(m)])
1031 return ", ".join(types)
1030 return ", ".join(types)
1032 type = property(gettype, None, None, "file type (file, directory, link, etc.)")
1031 type = property(gettype, None, None, "file type (file, directory, link, etc.)")
1033
1032
1034 def getmodestr(self):
1033 def getmodestr(self):
1035 m = self.mode
1034 m = self.mode
1036 data = [
1035 data = [
1037 (stat.S_IRUSR, "-r"),
1036 (stat.S_IRUSR, "-r"),
1038 (stat.S_IWUSR, "-w"),
1037 (stat.S_IWUSR, "-w"),
1039 (stat.S_IXUSR, "-x"),
1038 (stat.S_IXUSR, "-x"),
1040 (stat.S_IRGRP, "-r"),
1039 (stat.S_IRGRP, "-r"),
1041 (stat.S_IWGRP, "-w"),
1040 (stat.S_IWGRP, "-w"),
1042 (stat.S_IXGRP, "-x"),
1041 (stat.S_IXGRP, "-x"),
1043 (stat.S_IROTH, "-r"),
1042 (stat.S_IROTH, "-r"),
1044 (stat.S_IWOTH, "-w"),
1043 (stat.S_IWOTH, "-w"),
1045 (stat.S_IXOTH, "-x"),
1044 (stat.S_IXOTH, "-x"),
1046 ]
1045 ]
1047 return "".join([text[bool(m&bit)] for (bit, text) in data])
1046 return "".join([text[bool(m&bit)] for (bit, text) in data])
1048
1047
1049 modestr = property(getmodestr, None, None, "Access mode as string")
1048 modestr = property(getmodestr, None, None, "Access mode as string")
1050
1049
1051 def getblocks(self):
1050 def getblocks(self):
1052 return self.stat().st_blocks
1051 return self.stat().st_blocks
1053 blocks = property(getblocks, None, None, "File size in blocks")
1052 blocks = property(getblocks, None, None, "File size in blocks")
1054
1053
1055 def getblksize(self):
1054 def getblksize(self):
1056 return self.stat().st_blksize
1055 return self.stat().st_blksize
1057 blksize = property(getblksize, None, None, "Filesystem block size")
1056 blksize = property(getblksize, None, None, "Filesystem block size")
1058
1057
1059 def getdev(self):
1058 def getdev(self):
1060 return self.stat().st_dev
1059 return self.stat().st_dev
1061 dev = property(getdev)
1060 dev = property(getdev)
1062
1061
1063 def getnlink(self):
1062 def getnlink(self):
1064 return self.stat().st_nlink
1063 return self.stat().st_nlink
1065 nlink = property(getnlink, None, None, "Number of links")
1064 nlink = property(getnlink, None, None, "Number of links")
1066
1065
1067 def getuid(self):
1066 def getuid(self):
1068 return self.stat().st_uid
1067 return self.stat().st_uid
1069 uid = property(getuid, None, None, "User id of file owner")
1068 uid = property(getuid, None, None, "User id of file owner")
1070
1069
1071 def getgid(self):
1070 def getgid(self):
1072 return self.stat().st_gid
1071 return self.stat().st_gid
1073 gid = property(getgid, None, None, "Group id of file owner")
1072 gid = property(getgid, None, None, "Group id of file owner")
1074
1073
1075 def getowner(self):
1074 def getowner(self):
1076 stat = self.stat()
1075 stat = self.stat()
1077 try:
1076 try:
1078 return pwd.getpwuid(stat.st_uid).pw_name
1077 return pwd.getpwuid(stat.st_uid).pw_name
1079 except KeyError:
1078 except KeyError:
1080 return stat.st_uid
1079 return stat.st_uid
1081 owner = property(getowner, None, None, "Owner name (or id)")
1080 owner = property(getowner, None, None, "Owner name (or id)")
1082
1081
1083 def getgroup(self):
1082 def getgroup(self):
1084 stat = self.stat()
1083 stat = self.stat()
1085 try:
1084 try:
1086 return grp.getgrgid(stat.st_gid).gr_name
1085 return grp.getgrgid(stat.st_gid).gr_name
1087 except KeyError:
1086 except KeyError:
1088 return stat.st_gid
1087 return stat.st_gid
1089 group = property(getgroup, None, None, "Group name (or id)")
1088 group = property(getgroup, None, None, "Group name (or id)")
1090
1089
1091 def getadate(self):
1090 def getadate(self):
1092 return datetime.datetime.utcfromtimestamp(self.atime)
1091 return datetime.datetime.utcfromtimestamp(self.atime)
1093 adate = property(getadate, None, None, "Access date")
1092 adate = property(getadate, None, None, "Access date")
1094
1093
1095 def getcdate(self):
1094 def getcdate(self):
1096 return datetime.datetime.utcfromtimestamp(self.ctime)
1095 return datetime.datetime.utcfromtimestamp(self.ctime)
1097 cdate = property(getcdate, None, None, "Creation date")
1096 cdate = property(getcdate, None, None, "Creation date")
1098
1097
1099 def getmdate(self):
1098 def getmdate(self):
1100 return datetime.datetime.utcfromtimestamp(self.mtime)
1099 return datetime.datetime.utcfromtimestamp(self.mtime)
1101 mdate = property(getmdate, None, None, "Modification date")
1100 mdate = property(getmdate, None, None, "Modification date")
1102
1101
1103 def mimetype(self):
1102 def mimetype(self):
1104 """
1103 """
1105 Return MIME type guessed from the extension.
1104 Return MIME type guessed from the extension.
1106 """
1105 """
1107 return mimetypes.guess_type(self.basename())[0]
1106 return mimetypes.guess_type(self.basename())[0]
1108
1107
1109 def encoding(self):
1108 def encoding(self):
1110 """
1109 """
1111 Return guessed compression (like "compress" or "gzip").
1110 Return guessed compression (like "compress" or "gzip").
1112 """
1111 """
1113 return mimetypes.guess_type(self.basename())[1]
1112 return mimetypes.guess_type(self.basename())[1]
1114
1113
1115 def __repr__(self):
1114 def __repr__(self):
1116 return "ifile(%s)" % path._base.__repr__(self)
1115 return "ifile(%s)" % path._base.__repr__(self)
1117
1116
1118 if sys.platform == "win32":
1117 if sys.platform == "win32":
1119 defaultattrs = (None, "type", "size", "modestr", "mdate")
1118 defaultattrs = (None, "type", "size", "modestr", "mdate")
1120 else:
1119 else:
1121 defaultattrs = (None, "type", "size", "modestr", "owner", "group", "mdate")
1120 defaultattrs = (None, "type", "size", "modestr", "owner", "group", "mdate")
1122
1121
1123 def __xattrs__(self, mode="default"):
1122 def __xattrs__(self, mode="default"):
1124 if mode == "detail":
1123 if mode == "detail":
1125 return (
1124 return (
1126 "name",
1125 "name",
1127 "basename()",
1126 "basename()",
1128 "abspath()",
1127 "abspath()",
1129 "realpath()",
1128 "realpath()",
1130 "type",
1129 "type",
1131 "mode",
1130 "mode",
1132 "modestr",
1131 "modestr",
1133 "stat()",
1132 "stat()",
1134 "lstat()",
1133 "lstat()",
1135 "uid",
1134 "uid",
1136 "gid",
1135 "gid",
1137 "owner",
1136 "owner",
1138 "group",
1137 "group",
1139 "dev",
1138 "dev",
1140 "nlink",
1139 "nlink",
1141 "ctime",
1140 "ctime",
1142 "mtime",
1141 "mtime",
1143 "atime",
1142 "atime",
1144 "cdate",
1143 "cdate",
1145 "mdate",
1144 "mdate",
1146 "adate",
1145 "adate",
1147 "size",
1146 "size",
1148 "blocks",
1147 "blocks",
1149 "blksize",
1148 "blksize",
1150 "isdir()",
1149 "isdir()",
1151 "islink()",
1150 "islink()",
1152 "mimetype()",
1151 "mimetype()",
1153 "encoding()",
1152 "encoding()",
1154 "-listdir()",
1153 "-listdir()",
1155 "-dirs()",
1154 "-dirs()",
1156 "-files()",
1155 "-files()",
1157 "-walk()",
1156 "-walk()",
1158 "-walkdirs()",
1157 "-walkdirs()",
1159 "-walkfiles()",
1158 "-walkfiles()",
1160 )
1159 )
1161 else:
1160 else:
1162 return self.defaultattrs
1161 return self.defaultattrs
1163
1162
1164
1163
1165 def xiter_ifile(self):
1164 def xiter_ifile(self):
1166 if self.isdir():
1165 if self.isdir():
1167 yield (self / os.pardir).abspath()
1166 yield (self / os.pardir).abspath()
1168 for child in sorted(self.listdir()):
1167 for child in sorted(self.listdir()):
1169 yield child
1168 yield child
1170 else:
1169 else:
1171 f = self.open("rb")
1170 f = self.open("rb")
1172 for line in f:
1171 for line in f:
1173 yield line
1172 yield line
1174 f.close()
1173 f.close()
1175 xiter.when_type(ifile)(xiter_ifile)
1174 xiter.when_type(ifile)(xiter_ifile)
1176
1175
1177
1176
1178 # We need to implement ``xrepr`` for ``ifile`` as a generic function, because
1177 # We need to implement ``xrepr`` for ``ifile`` as a generic function, because
1179 # otherwise ``xrepr_str`` would kick in.
1178 # otherwise ``xrepr_str`` would kick in.
1180 def xrepr_ifile(self, mode="default"):
1179 def xrepr_ifile(self, mode="default"):
1181 try:
1180 try:
1182 if self.isdir():
1181 if self.isdir():
1183 name = "idir"
1182 name = "idir"
1184 style = astyle.style_dir
1183 style = astyle.style_dir
1185 else:
1184 else:
1186 name = "ifile"
1185 name = "ifile"
1187 style = astyle.style_file
1186 style = astyle.style_file
1188 except IOError:
1187 except IOError:
1189 name = "ifile"
1188 name = "ifile"
1190 style = astyle.style_default
1189 style = astyle.style_default
1191 if mode in ("cell", "header", "footer"):
1190 if mode in ("cell", "header", "footer"):
1192 abspath = repr(path._base(self.normpath()))
1191 abspath = repr(path._base(self.normpath()))
1193 if abspath.startswith("u"):
1192 if abspath.startswith("u"):
1194 abspath = abspath[2:-1]
1193 abspath = abspath[2:-1]
1195 else:
1194 else:
1196 abspath = abspath[1:-1]
1195 abspath = abspath[1:-1]
1197 if mode == "cell":
1196 if mode == "cell":
1198 yield (style, abspath)
1197 yield (style, abspath)
1199 else:
1198 else:
1200 yield (style, "%s(%s)" % (name, abspath))
1199 yield (style, "%s(%s)" % (name, abspath))
1201 else:
1200 else:
1202 yield (style, repr(self))
1201 yield (style, repr(self))
1203 xrepr.when_type(ifile)(xrepr_ifile)
1202 xrepr.when_type(ifile)(xrepr_ifile)
1204
1203
1205
1204
1206 class ils(Table):
1205 class ils(Table):
1207 """
1206 """
1208 List the current (or a specified) directory.
1207 List the current (or a specified) directory.
1209
1208
1210 Examples::
1209 Examples::
1211
1210
1212 >>> ils
1211 py> ils
1213 >>> ils("/usr/local/lib/python2.4")
1212 py> ils("/usr/local/lib/python2.4")
1214 >>> ils("~")
1213 py> ils("~")
1215 """
1214 """
1216 def __init__(self, base=os.curdir, dirs=True, files=True):
1215 def __init__(self, base=os.curdir, dirs=True, files=True):
1217 self.base = os.path.expanduser(base)
1216 self.base = os.path.expanduser(base)
1218 self.dirs = dirs
1217 self.dirs = dirs
1219 self.files = files
1218 self.files = files
1220
1219
1221 def __iter__(self):
1220 def __iter__(self):
1222 base = ifile(self.base)
1221 base = ifile(self.base)
1223 yield (base / os.pardir).abspath()
1222 yield (base / os.pardir).abspath()
1224 for child in sorted(base.listdir()):
1223 for child in sorted(base.listdir()):
1225 if self.dirs:
1224 if self.dirs:
1226 if self.files:
1225 if self.files:
1227 yield child
1226 yield child
1228 else:
1227 else:
1229 if child.isdir():
1228 if child.isdir():
1230 yield child
1229 yield child
1231 elif self.files:
1230 elif self.files:
1232 if not child.isdir():
1231 if not child.isdir():
1233 yield child
1232 yield child
1234
1233
1235 def __xrepr__(self, mode="default"):
1234 def __xrepr__(self, mode="default"):
1236 return xrepr(ifile(self.base), mode)
1235 return xrepr(ifile(self.base), mode)
1237
1236
1238 def __repr__(self):
1237 def __repr__(self):
1239 return "%s.%s(%r)" % \
1238 return "%s.%s(%r)" % \
1240 (self.__class__.__module__, self.__class__.__name__, self.base)
1239 (self.__class__.__module__, self.__class__.__name__, self.base)
1241
1240
1242
1241
1243 class iglob(Table):
1242 class iglob(Table):
1244 """
1243 """
1245 List all files and directories matching a specified pattern.
1244 List all files and directories matching a specified pattern.
1246 (See ``glob.glob()`` for more info.).
1245 (See ``glob.glob()`` for more info.).
1247
1246
1248 Examples::
1247 Examples::
1249
1248
1250 >>> iglob("*.py")
1249 py> iglob("*.py")
1251 """
1250 """
1252 def __init__(self, glob):
1251 def __init__(self, glob):
1253 self.glob = glob
1252 self.glob = glob
1254
1253
1255 def __iter__(self):
1254 def __iter__(self):
1256 for name in glob.glob(self.glob):
1255 for name in glob.glob(self.glob):
1257 yield ifile(name)
1256 yield ifile(name)
1258
1257
1259 def __xrepr__(self, mode="default"):
1258 def __xrepr__(self, mode="default"):
1260 if mode == "header" or mode == "footer" or mode == "cell":
1259 if mode == "header" or mode == "footer" or mode == "cell":
1261 yield (astyle.style_default,
1260 yield (astyle.style_default,
1262 "%s(%r)" % (self.__class__.__name__, self.glob))
1261 "%s(%r)" % (self.__class__.__name__, self.glob))
1263 else:
1262 else:
1264 yield (astyle.style_default, repr(self))
1263 yield (astyle.style_default, repr(self))
1265
1264
1266 def __repr__(self):
1265 def __repr__(self):
1267 return "%s.%s(%r)" % \
1266 return "%s.%s(%r)" % \
1268 (self.__class__.__module__, self.__class__.__name__, self.glob)
1267 (self.__class__.__module__, self.__class__.__name__, self.glob)
1269
1268
1270
1269
1271 class iwalk(Table):
1270 class iwalk(Table):
1272 """
1271 """
1273 List all files and directories in a directory and it's subdirectory::
1272 List all files and directories in a directory and it's subdirectory::
1274
1273
1275 >>> iwalk
1274 py> iwalk
1276 >>> iwalk("/usr/local/lib/python2.4")
1275 py> iwalk("/usr/local/lib/python2.4")
1277 >>> iwalk("~")
1276 py> iwalk("~")
1278 """
1277 """
1279 def __init__(self, base=os.curdir, dirs=True, files=True):
1278 def __init__(self, base=os.curdir, dirs=True, files=True):
1280 self.base = os.path.expanduser(base)
1279 self.base = os.path.expanduser(base)
1281 self.dirs = dirs
1280 self.dirs = dirs
1282 self.files = files
1281 self.files = files
1283
1282
1284 def __iter__(self):
1283 def __iter__(self):
1285 for (dirpath, dirnames, filenames) in os.walk(self.base):
1284 for (dirpath, dirnames, filenames) in os.walk(self.base):
1286 if self.dirs:
1285 if self.dirs:
1287 for name in sorted(dirnames):
1286 for name in sorted(dirnames):
1288 yield ifile(os.path.join(dirpath, name))
1287 yield ifile(os.path.join(dirpath, name))
1289 if self.files:
1288 if self.files:
1290 for name in sorted(filenames):
1289 for name in sorted(filenames):
1291 yield ifile(os.path.join(dirpath, name))
1290 yield ifile(os.path.join(dirpath, name))
1292
1291
1293 def __xrepr__(self, mode="default"):
1292 def __xrepr__(self, mode="default"):
1294 if mode == "header" or mode == "footer" or mode == "cell":
1293 if mode == "header" or mode == "footer" or mode == "cell":
1295 yield (astyle.style_default,
1294 yield (astyle.style_default,
1296 "%s(%r)" % (self.__class__.__name__, self.base))
1295 "%s(%r)" % (self.__class__.__name__, self.base))
1297 else:
1296 else:
1298 yield (astyle.style_default, repr(self))
1297 yield (astyle.style_default, repr(self))
1299
1298
1300 def __repr__(self):
1299 def __repr__(self):
1301 return "%s.%s(%r)" % \
1300 return "%s.%s(%r)" % \
1302 (self.__class__.__module__, self.__class__.__name__, self.base)
1301 (self.__class__.__module__, self.__class__.__name__, self.base)
1303
1302
1304
1303
1305 class ipwdentry(object):
1304 class ipwdentry(object):
1306 """
1305 """
1307 ``ipwdentry`` objects encapsulate entries in the Unix user account and
1306 ``ipwdentry`` objects encapsulate entries in the Unix user account and
1308 password database.
1307 password database.
1309 """
1308 """
1310 def __init__(self, id):
1309 def __init__(self, id):
1311 self._id = id
1310 self._id = id
1312 self._entry = None
1311 self._entry = None
1313
1312
1314 def __eq__(self, other):
1313 def __eq__(self, other):
1315 return self.__class__ is other.__class__ and self._id == other._id
1314 return self.__class__ is other.__class__ and self._id == other._id
1316
1315
1317 def __ne__(self, other):
1316 def __ne__(self, other):
1318 return self.__class__ is not other.__class__ or self._id != other._id
1317 return self.__class__ is not other.__class__ or self._id != other._id
1319
1318
1320 def _getentry(self):
1319 def _getentry(self):
1321 if self._entry is None:
1320 if self._entry is None:
1322 if isinstance(self._id, basestring):
1321 if isinstance(self._id, basestring):
1323 self._entry = pwd.getpwnam(self._id)
1322 self._entry = pwd.getpwnam(self._id)
1324 else:
1323 else:
1325 self._entry = pwd.getpwuid(self._id)
1324 self._entry = pwd.getpwuid(self._id)
1326 return self._entry
1325 return self._entry
1327
1326
1328 def getname(self):
1327 def getname(self):
1329 if isinstance(self._id, basestring):
1328 if isinstance(self._id, basestring):
1330 return self._id
1329 return self._id
1331 else:
1330 else:
1332 return self._getentry().pw_name
1331 return self._getentry().pw_name
1333 name = property(getname, None, None, "User name")
1332 name = property(getname, None, None, "User name")
1334
1333
1335 def getpasswd(self):
1334 def getpasswd(self):
1336 return self._getentry().pw_passwd
1335 return self._getentry().pw_passwd
1337 passwd = property(getpasswd, None, None, "Password")
1336 passwd = property(getpasswd, None, None, "Password")
1338
1337
1339 def getuid(self):
1338 def getuid(self):
1340 if isinstance(self._id, basestring):
1339 if isinstance(self._id, basestring):
1341 return self._getentry().pw_uid
1340 return self._getentry().pw_uid
1342 else:
1341 else:
1343 return self._id
1342 return self._id
1344 uid = property(getuid, None, None, "User id")
1343 uid = property(getuid, None, None, "User id")
1345
1344
1346 def getgid(self):
1345 def getgid(self):
1347 return self._getentry().pw_gid
1346 return self._getentry().pw_gid
1348 gid = property(getgid, None, None, "Primary group id")
1347 gid = property(getgid, None, None, "Primary group id")
1349
1348
1350 def getgroup(self):
1349 def getgroup(self):
1351 return igrpentry(self.gid)
1350 return igrpentry(self.gid)
1352 group = property(getgroup, None, None, "Group")
1351 group = property(getgroup, None, None, "Group")
1353
1352
1354 def getgecos(self):
1353 def getgecos(self):
1355 return self._getentry().pw_gecos
1354 return self._getentry().pw_gecos
1356 gecos = property(getgecos, None, None, "Information (e.g. full user name)")
1355 gecos = property(getgecos, None, None, "Information (e.g. full user name)")
1357
1356
1358 def getdir(self):
1357 def getdir(self):
1359 return self._getentry().pw_dir
1358 return self._getentry().pw_dir
1360 dir = property(getdir, None, None, "$HOME directory")
1359 dir = property(getdir, None, None, "$HOME directory")
1361
1360
1362 def getshell(self):
1361 def getshell(self):
1363 return self._getentry().pw_shell
1362 return self._getentry().pw_shell
1364 shell = property(getshell, None, None, "Login shell")
1363 shell = property(getshell, None, None, "Login shell")
1365
1364
1366 def __xattrs__(self, mode="default"):
1365 def __xattrs__(self, mode="default"):
1367 return ("name", "passwd", "uid", "gid", "gecos", "dir", "shell")
1366 return ("name", "passwd", "uid", "gid", "gecos", "dir", "shell")
1368
1367
1369 def __repr__(self):
1368 def __repr__(self):
1370 return "%s.%s(%r)" % \
1369 return "%s.%s(%r)" % \
1371 (self.__class__.__module__, self.__class__.__name__, self._id)
1370 (self.__class__.__module__, self.__class__.__name__, self._id)
1372
1371
1373
1372
1374 class ipwd(Table):
1373 class ipwd(Table):
1375 """
1374 """
1376 List all entries in the Unix user account and password database.
1375 List all entries in the Unix user account and password database.
1377
1376
1378 Example::
1377 Example::
1379
1378
1380 >>> ipwd | isort("uid")
1379 py> ipwd | isort("uid")
1381 """
1380 """
1382 def __iter__(self):
1381 def __iter__(self):
1383 for entry in pwd.getpwall():
1382 for entry in pwd.getpwall():
1384 yield ipwdentry(entry.pw_name)
1383 yield ipwdentry(entry.pw_name)
1385
1384
1386 def __xrepr__(self, mode="default"):
1385 def __xrepr__(self, mode="default"):
1387 if mode == "header" or mode == "footer" or mode == "cell":
1386 if mode == "header" or mode == "footer" or mode == "cell":
1388 yield (astyle.style_default, "%s()" % self.__class__.__name__)
1387 yield (astyle.style_default, "%s()" % self.__class__.__name__)
1389 else:
1388 else:
1390 yield (astyle.style_default, repr(self))
1389 yield (astyle.style_default, repr(self))
1391
1390
1392
1391
1393 class igrpentry(object):
1392 class igrpentry(object):
1394 """
1393 """
1395 ``igrpentry`` objects encapsulate entries in the Unix group database.
1394 ``igrpentry`` objects encapsulate entries in the Unix group database.
1396 """
1395 """
1397 def __init__(self, id):
1396 def __init__(self, id):
1398 self._id = id
1397 self._id = id
1399 self._entry = None
1398 self._entry = None
1400
1399
1401 def __eq__(self, other):
1400 def __eq__(self, other):
1402 return self.__class__ is other.__class__ and self._id == other._id
1401 return self.__class__ is other.__class__ and self._id == other._id
1403
1402
1404 def __ne__(self, other):
1403 def __ne__(self, other):
1405 return self.__class__ is not other.__class__ or self._id != other._id
1404 return self.__class__ is not other.__class__ or self._id != other._id
1406
1405
1407 def _getentry(self):
1406 def _getentry(self):
1408 if self._entry is None:
1407 if self._entry is None:
1409 if isinstance(self._id, basestring):
1408 if isinstance(self._id, basestring):
1410 self._entry = grp.getgrnam(self._id)
1409 self._entry = grp.getgrnam(self._id)
1411 else:
1410 else:
1412 self._entry = grp.getgrgid(self._id)
1411 self._entry = grp.getgrgid(self._id)
1413 return self._entry
1412 return self._entry
1414
1413
1415 def getname(self):
1414 def getname(self):
1416 if isinstance(self._id, basestring):
1415 if isinstance(self._id, basestring):
1417 return self._id
1416 return self._id
1418 else:
1417 else:
1419 return self._getentry().gr_name
1418 return self._getentry().gr_name
1420 name = property(getname, None, None, "Group name")
1419 name = property(getname, None, None, "Group name")
1421
1420
1422 def getpasswd(self):
1421 def getpasswd(self):
1423 return self._getentry().gr_passwd
1422 return self._getentry().gr_passwd
1424 passwd = property(getpasswd, None, None, "Password")
1423 passwd = property(getpasswd, None, None, "Password")
1425
1424
1426 def getgid(self):
1425 def getgid(self):
1427 if isinstance(self._id, basestring):
1426 if isinstance(self._id, basestring):
1428 return self._getentry().gr_gid
1427 return self._getentry().gr_gid
1429 else:
1428 else:
1430 return self._id
1429 return self._id
1431 gid = property(getgid, None, None, "Group id")
1430 gid = property(getgid, None, None, "Group id")
1432
1431
1433 def getmem(self):
1432 def getmem(self):
1434 return self._getentry().gr_mem
1433 return self._getentry().gr_mem
1435 mem = property(getmem, None, None, "Members")
1434 mem = property(getmem, None, None, "Members")
1436
1435
1437 def __xattrs__(self, mode="default"):
1436 def __xattrs__(self, mode="default"):
1438 return ("name", "passwd", "gid", "mem")
1437 return ("name", "passwd", "gid", "mem")
1439
1438
1440 def __xrepr__(self, mode="default"):
1439 def __xrepr__(self, mode="default"):
1441 if mode == "header" or mode == "footer" or mode == "cell":
1440 if mode == "header" or mode == "footer" or mode == "cell":
1442 yield (astyle.style_default, "group ")
1441 yield (astyle.style_default, "group ")
1443 try:
1442 try:
1444 yield (astyle.style_default, self.name)
1443 yield (astyle.style_default, self.name)
1445 except KeyError:
1444 except KeyError:
1446 if isinstance(self._id, basestring):
1445 if isinstance(self._id, basestring):
1447 yield (astyle.style_default, self.name_id)
1446 yield (astyle.style_default, self.name_id)
1448 else:
1447 else:
1449 yield (astyle.style_type_number, str(self._id))
1448 yield (astyle.style_type_number, str(self._id))
1450 else:
1449 else:
1451 yield (astyle.style_default, repr(self))
1450 yield (astyle.style_default, repr(self))
1452
1451
1453 def __iter__(self):
1452 def __iter__(self):
1454 for member in self.mem:
1453 for member in self.mem:
1455 yield ipwdentry(member)
1454 yield ipwdentry(member)
1456
1455
1457 def __repr__(self):
1456 def __repr__(self):
1458 return "%s.%s(%r)" % \
1457 return "%s.%s(%r)" % \
1459 (self.__class__.__module__, self.__class__.__name__, self._id)
1458 (self.__class__.__module__, self.__class__.__name__, self._id)
1460
1459
1461
1460
1462 class igrp(Table):
1461 class igrp(Table):
1463 """
1462 """
1464 This ``Table`` lists all entries in the Unix group database.
1463 This ``Table`` lists all entries in the Unix group database.
1465 """
1464 """
1466 def __iter__(self):
1465 def __iter__(self):
1467 for entry in grp.getgrall():
1466 for entry in grp.getgrall():
1468 yield igrpentry(entry.gr_name)
1467 yield igrpentry(entry.gr_name)
1469
1468
1470 def __xrepr__(self, mode="default"):
1469 def __xrepr__(self, mode="default"):
1471 if mode == "header" or mode == "footer":
1470 if mode == "header" or mode == "footer":
1472 yield (astyle.style_default, "%s()" % self.__class__.__name__)
1471 yield (astyle.style_default, "%s()" % self.__class__.__name__)
1473 else:
1472 else:
1474 yield (astyle.style_default, repr(self))
1473 yield (astyle.style_default, repr(self))
1475
1474
1476
1475
1477 class Fields(object):
1476 class Fields(object):
1478 def __init__(self, fieldnames, **fields):
1477 def __init__(self, fieldnames, **fields):
1479 self.__fieldnames = [upgradexattr(fieldname) for fieldname in fieldnames]
1478 self.__fieldnames = [upgradexattr(fieldname) for fieldname in fieldnames]
1480 for (key, value) in fields.iteritems():
1479 for (key, value) in fields.iteritems():
1481 setattr(self, key, value)
1480 setattr(self, key, value)
1482
1481
1483 def __xattrs__(self, mode="default"):
1482 def __xattrs__(self, mode="default"):
1484 return self.__fieldnames
1483 return self.__fieldnames
1485
1484
1486 def __xrepr__(self, mode="default"):
1485 def __xrepr__(self, mode="default"):
1487 yield (-1, False)
1486 yield (-1, False)
1488 if mode == "header" or mode == "cell":
1487 if mode == "header" or mode == "cell":
1489 yield (astyle.style_default, self.__class__.__name__)
1488 yield (astyle.style_default, self.__class__.__name__)
1490 yield (astyle.style_default, "(")
1489 yield (astyle.style_default, "(")
1491 for (i, f) in enumerate(self.__fieldnames):
1490 for (i, f) in enumerate(self.__fieldnames):
1492 if i:
1491 if i:
1493 yield (astyle.style_default, ", ")
1492 yield (astyle.style_default, ", ")
1494 yield (astyle.style_default, f.name())
1493 yield (astyle.style_default, f.name())
1495 yield (astyle.style_default, "=")
1494 yield (astyle.style_default, "=")
1496 for part in xrepr(getattr(self, f), "default"):
1495 for part in xrepr(getattr(self, f), "default"):
1497 yield part
1496 yield part
1498 yield (astyle.style_default, ")")
1497 yield (astyle.style_default, ")")
1499 elif mode == "footer":
1498 elif mode == "footer":
1500 yield (astyle.style_default, self.__class__.__name__)
1499 yield (astyle.style_default, self.__class__.__name__)
1501 yield (astyle.style_default, "(")
1500 yield (astyle.style_default, "(")
1502 for (i, f) in enumerate(self.__fieldnames):
1501 for (i, f) in enumerate(self.__fieldnames):
1503 if i:
1502 if i:
1504 yield (astyle.style_default, ", ")
1503 yield (astyle.style_default, ", ")
1505 yield (astyle.style_default, f.name())
1504 yield (astyle.style_default, f.name())
1506 yield (astyle.style_default, ")")
1505 yield (astyle.style_default, ")")
1507 else:
1506 else:
1508 yield (astyle.style_default, repr(self))
1507 yield (astyle.style_default, repr(self))
1509
1508
1510
1509
1511 class FieldTable(Table, list):
1510 class FieldTable(Table, list):
1512 def __init__(self, *fields):
1511 def __init__(self, *fields):
1513 Table.__init__(self)
1512 Table.__init__(self)
1514 list.__init__(self)
1513 list.__init__(self)
1515 self.fields = fields
1514 self.fields = fields
1516
1515
1517 def add(self, **fields):
1516 def add(self, **fields):
1518 self.append(Fields(self.fields, **fields))
1517 self.append(Fields(self.fields, **fields))
1519
1518
1520 def __xrepr__(self, mode="default"):
1519 def __xrepr__(self, mode="default"):
1521 yield (-1, False)
1520 yield (-1, False)
1522 if mode == "header" or mode == "footer":
1521 if mode == "header" or mode == "footer":
1523 yield (astyle.style_default, self.__class__.__name__)
1522 yield (astyle.style_default, self.__class__.__name__)
1524 yield (astyle.style_default, "(")
1523 yield (astyle.style_default, "(")
1525 for (i, f) in enumerate(self.__fieldnames):
1524 for (i, f) in enumerate(self.__fieldnames):
1526 if i:
1525 if i:
1527 yield (astyle.style_default, ", ")
1526 yield (astyle.style_default, ", ")
1528 yield (astyle.style_default, f)
1527 yield (astyle.style_default, f)
1529 yield (astyle.style_default, ")")
1528 yield (astyle.style_default, ")")
1530 else:
1529 else:
1531 yield (astyle.style_default, repr(self))
1530 yield (astyle.style_default, repr(self))
1532
1531
1533 def __repr__(self):
1532 def __repr__(self):
1534 return "<%s.%s object with fields=%r at 0x%x>" % \
1533 return "<%s.%s object with fields=%r at 0x%x>" % \
1535 (self.__class__.__module__, self.__class__.__name__,
1534 (self.__class__.__module__, self.__class__.__name__,
1536 ", ".join(map(repr, self.fields)), id(self))
1535 ", ".join(map(repr, self.fields)), id(self))
1537
1536
1538
1537
1539 class List(list):
1538 class List(list):
1540 def __xattrs__(self, mode="default"):
1539 def __xattrs__(self, mode="default"):
1541 return xrange(len(self))
1540 return xrange(len(self))
1542
1541
1543 def __xrepr__(self, mode="default"):
1542 def __xrepr__(self, mode="default"):
1544 yield (-1, False)
1543 yield (-1, False)
1545 if mode == "header" or mode == "cell" or mode == "footer" or mode == "default":
1544 if mode == "header" or mode == "cell" or mode == "footer" or mode == "default":
1546 yield (astyle.style_default, self.__class__.__name__)
1545 yield (astyle.style_default, self.__class__.__name__)
1547 yield (astyle.style_default, "(")
1546 yield (astyle.style_default, "(")
1548 for (i, item) in enumerate(self):
1547 for (i, item) in enumerate(self):
1549 if i:
1548 if i:
1550 yield (astyle.style_default, ", ")
1549 yield (astyle.style_default, ", ")
1551 for part in xrepr(item, "default"):
1550 for part in xrepr(item, "default"):
1552 yield part
1551 yield part
1553 yield (astyle.style_default, ")")
1552 yield (astyle.style_default, ")")
1554 else:
1553 else:
1555 yield (astyle.style_default, repr(self))
1554 yield (astyle.style_default, repr(self))
1556
1555
1557
1556
1558 class ienv(Table):
1557 class ienv(Table):
1559 """
1558 """
1560 List environment variables.
1559 List environment variables.
1561
1560
1562 Example::
1561 Example::
1563
1562
1564 >>> ienv
1563 py> ienv
1565 """
1564 """
1566
1565
1567 def __iter__(self):
1566 def __iter__(self):
1568 fields = ("key", "value")
1567 fields = ("key", "value")
1569 for (key, value) in os.environ.iteritems():
1568 for (key, value) in os.environ.iteritems():
1570 yield Fields(fields, key=key, value=value)
1569 yield Fields(fields, key=key, value=value)
1571
1570
1572 def __xrepr__(self, mode="default"):
1571 def __xrepr__(self, mode="default"):
1573 if mode == "header" or mode == "cell":
1572 if mode == "header" or mode == "cell":
1574 yield (astyle.style_default, "%s()" % self.__class__.__name__)
1573 yield (astyle.style_default, "%s()" % self.__class__.__name__)
1575 else:
1574 else:
1576 yield (astyle.style_default, repr(self))
1575 yield (astyle.style_default, repr(self))
1577
1576
1578
1577
1579 class ihist(Table):
1578 class ihist(Table):
1580 """
1579 """
1581 IPython input history
1580 IPython input history
1582
1581
1583 Example::
1582 Example::
1584
1583
1585 >>> ihist
1584 py> ihist
1586 >>> ihist(True) (raw mode)
1585 py> ihist(True) (raw mode)
1587 """
1586 """
1588 def __init__(self, raw=True):
1587 def __init__(self, raw=True):
1589 self.raw = raw
1588 self.raw = raw
1590
1589
1591 def __iter__(self):
1590 def __iter__(self):
1592 api = ipapi.get()
1591 api = ipapi.get()
1593 if self.raw:
1592 if self.raw:
1594 for line in api.IP.input_hist_raw:
1593 for line in api.IP.input_hist_raw:
1595 yield line.rstrip("\n")
1594 yield line.rstrip("\n")
1596 else:
1595 else:
1597 for line in api.IP.input_hist:
1596 for line in api.IP.input_hist:
1598 yield line.rstrip("\n")
1597 yield line.rstrip("\n")
1599
1598
1600
1599
1601 class Alias(object):
1600 class Alias(object):
1602 """
1601 """
1603 Entry in the alias table
1602 Entry in the alias table
1604 """
1603 """
1605 def __init__(self, name, args, command):
1604 def __init__(self, name, args, command):
1606 self.name = name
1605 self.name = name
1607 self.args = args
1606 self.args = args
1608 self.command = command
1607 self.command = command
1609
1608
1610 def __xattrs__(self, mode="default"):
1609 def __xattrs__(self, mode="default"):
1611 return ("name", "args", "command")
1610 return ("name", "args", "command")
1612
1611
1613
1612
1614 class ialias(Table):
1613 class ialias(Table):
1615 """
1614 """
1616 IPython alias list
1615 IPython alias list
1617
1616
1618 Example::
1617 Example::
1619
1618
1620 >>> ialias
1619 py> ialias
1621 """
1620 """
1622 def __iter__(self):
1621 def __iter__(self):
1623 api = ipapi.get()
1622 api = ipapi.get()
1624
1623
1625 for (name, (args, command)) in api.IP.alias_table.iteritems():
1624 for (name, (args, command)) in api.IP.alias_table.iteritems():
1626 yield Alias(name, args, command)
1625 yield Alias(name, args, command)
1627
1626
1628
1627
1629 class icsv(Pipe):
1628 class icsv(Pipe):
1630 """
1629 """
1631 This ``Pipe`` turns the input (with must be a pipe outputting lines
1630 This ``Pipe`` turns the input (with must be a pipe outputting lines
1632 or an ``ifile``) into lines of CVS columns.
1631 or an ``ifile``) into lines of CVS columns.
1633 """
1632 """
1634 def __init__(self, **csvargs):
1633 def __init__(self, **csvargs):
1635 """
1634 """
1636 Create an ``icsv`` object. ``cvsargs`` will be passed through as
1635 Create an ``icsv`` object. ``cvsargs`` will be passed through as
1637 keyword arguments to ``cvs.reader()``.
1636 keyword arguments to ``cvs.reader()``.
1638 """
1637 """
1639 self.csvargs = csvargs
1638 self.csvargs = csvargs
1640
1639
1641 def __iter__(self):
1640 def __iter__(self):
1642 input = self.input
1641 input = self.input
1643 if isinstance(input, ifile):
1642 if isinstance(input, ifile):
1644 input = input.open("rb")
1643 input = input.open("rb")
1645 reader = csv.reader(input, **self.csvargs)
1644 reader = csv.reader(input, **self.csvargs)
1646 for line in reader:
1645 for line in reader:
1647 yield List(line)
1646 yield List(line)
1648
1647
1649 def __xrepr__(self, mode="default"):
1648 def __xrepr__(self, mode="default"):
1650 yield (-1, False)
1649 yield (-1, False)
1651 if mode == "header" or mode == "footer":
1650 if mode == "header" or mode == "footer":
1652 input = getattr(self, "input", None)
1651 input = getattr(self, "input", None)
1653 if input is not None:
1652 if input is not None:
1654 for part in xrepr(input, mode):
1653 for part in xrepr(input, mode):
1655 yield part
1654 yield part
1656 yield (astyle.style_default, " | ")
1655 yield (astyle.style_default, " | ")
1657 yield (astyle.style_default, "%s(" % self.__class__.__name__)
1656 yield (astyle.style_default, "%s(" % self.__class__.__name__)
1658 for (i, (name, value)) in enumerate(self.csvargs.iteritems()):
1657 for (i, (name, value)) in enumerate(self.csvargs.iteritems()):
1659 if i:
1658 if i:
1660 yield (astyle.style_default, ", ")
1659 yield (astyle.style_default, ", ")
1661 yield (astyle.style_default, name)
1660 yield (astyle.style_default, name)
1662 yield (astyle.style_default, "=")
1661 yield (astyle.style_default, "=")
1663 for part in xrepr(value, "default"):
1662 for part in xrepr(value, "default"):
1664 yield part
1663 yield part
1665 yield (astyle.style_default, ")")
1664 yield (astyle.style_default, ")")
1666 else:
1665 else:
1667 yield (astyle.style_default, repr(self))
1666 yield (astyle.style_default, repr(self))
1668
1667
1669 def __repr__(self):
1668 def __repr__(self):
1670 args = ", ".join(["%s=%r" % item for item in self.csvargs.iteritems()])
1669 args = ", ".join(["%s=%r" % item for item in self.csvargs.iteritems()])
1671 return "<%s.%s %s at 0x%x>" % \
1670 return "<%s.%s %s at 0x%x>" % \
1672 (self.__class__.__module__, self.__class__.__name__, args, id(self))
1671 (self.__class__.__module__, self.__class__.__name__, args, id(self))
1673
1672
1674
1673
1675 class ix(Table):
1674 class ix(Table):
1676 """
1675 """
1677 Execute a system command and list its output as lines
1676 Execute a system command and list its output as lines
1678 (similar to ``os.popen()``).
1677 (similar to ``os.popen()``).
1679
1678
1680 Examples::
1679 Examples::
1681
1680
1682 >>> ix("ps x")
1681 py> ix("ps x")
1683 >>> ix("find .") | ifile
1682 py> ix("find .") | ifile
1684 """
1683 """
1685 def __init__(self, cmd):
1684 def __init__(self, cmd):
1686 self.cmd = cmd
1685 self.cmd = cmd
1687 self._pipeout = None
1686 self._pipeout = None
1688
1687
1689 def __iter__(self):
1688 def __iter__(self):
1690 (_pipein, self._pipeout) = os.popen4(self.cmd)
1689 (_pipein, self._pipeout) = os.popen4(self.cmd)
1691 _pipein.close()
1690 _pipein.close()
1692 for l in self._pipeout:
1691 for l in self._pipeout:
1693 yield l.rstrip("\r\n")
1692 yield l.rstrip("\r\n")
1694 self._pipeout.close()
1693 self._pipeout.close()
1695 self._pipeout = None
1694 self._pipeout = None
1696
1695
1697 def __del__(self):
1696 def __del__(self):
1698 if self._pipeout is not None and not self._pipeout.closed:
1697 if self._pipeout is not None and not self._pipeout.closed:
1699 self._pipeout.close()
1698 self._pipeout.close()
1700 self._pipeout = None
1699 self._pipeout = None
1701
1700
1702 def __xrepr__(self, mode="default"):
1701 def __xrepr__(self, mode="default"):
1703 if mode == "header" or mode == "footer":
1702 if mode == "header" or mode == "footer":
1704 yield (astyle.style_default,
1703 yield (astyle.style_default,
1705 "%s(%r)" % (self.__class__.__name__, self.cmd))
1704 "%s(%r)" % (self.__class__.__name__, self.cmd))
1706 else:
1705 else:
1707 yield (astyle.style_default, repr(self))
1706 yield (astyle.style_default, repr(self))
1708
1707
1709 def __repr__(self):
1708 def __repr__(self):
1710 return "%s.%s(%r)" % \
1709 return "%s.%s(%r)" % \
1711 (self.__class__.__module__, self.__class__.__name__, self.cmd)
1710 (self.__class__.__module__, self.__class__.__name__, self.cmd)
1712
1711
1713
1712
1714 class ifilter(Pipe):
1713 class ifilter(Pipe):
1715 """
1714 """
1716 Filter an input pipe. Only objects where an expression evaluates to true
1715 Filter an input pipe. Only objects where an expression evaluates to true
1717 (and doesn't raise an exception) are listed.
1716 (and doesn't raise an exception) are listed.
1718
1717
1719 Examples::
1718 Examples::
1720
1719
1721 >>> ils | ifilter("_.isfile() and size>1000")
1720 py> ils | ifilter("_.isfile() and size>1000")
1722 >>> igrp | ifilter("len(mem)")
1721 py> igrp | ifilter("len(mem)")
1723 >>> sys.modules | ifilter(lambda _:_.value is not None)
1722 py> sys.modules | ifilter(lambda _:_.value is not None)
1724 """
1723 """
1725
1724
1726 def __init__(self, expr, globals=None, errors="raiseifallfail"):
1725 def __init__(self, expr, globals=None, errors="raiseifallfail"):
1727 """
1726 """
1728 Create an ``ifilter`` object. ``expr`` can be a callable or a string
1727 Create an ``ifilter`` object. ``expr`` can be a callable or a string
1729 containing an expression. ``globals`` will be used as the global
1728 containing an expression. ``globals`` will be used as the global
1730 namespace for calling string expressions (defaulting to IPython's
1729 namespace for calling string expressions (defaulting to IPython's
1731 user namespace). ``errors`` specifies how exception during evaluation
1730 user namespace). ``errors`` specifies how exception during evaluation
1732 of ``expr`` are handled:
1731 of ``expr`` are handled:
1733
1732
1734 ``"drop"``
1733 ``"drop"``
1735 drop all items that have errors;
1734 drop all items that have errors;
1736
1735
1737 ``"keep"``
1736 ``"keep"``
1738 keep all items that have errors;
1737 keep all items that have errors;
1739
1738
1740 ``"keeperror"``
1739 ``"keeperror"``
1741 keep the exception of all items that have errors;
1740 keep the exception of all items that have errors;
1742
1741
1743 ``"raise"``
1742 ``"raise"``
1744 raise the exception;
1743 raise the exception;
1745
1744
1746 ``"raiseifallfail"``
1745 ``"raiseifallfail"``
1747 raise the first exception if all items have errors; otherwise drop
1746 raise the first exception if all items have errors; otherwise drop
1748 those with errors (this is the default).
1747 those with errors (this is the default).
1749 """
1748 """
1750 self.expr = expr
1749 self.expr = expr
1751 self.globals = globals
1750 self.globals = globals
1752 self.errors = errors
1751 self.errors = errors
1753
1752
1754 def __iter__(self):
1753 def __iter__(self):
1755 if callable(self.expr):
1754 if callable(self.expr):
1756 test = self.expr
1755 test = self.expr
1757 else:
1756 else:
1758 g = getglobals(self.globals)
1757 g = getglobals(self.globals)
1759 expr = compile(self.expr, "ipipe-expression", "eval")
1758 expr = compile(self.expr, "ipipe-expression", "eval")
1760 def test(item):
1759 def test(item):
1761 return eval(expr, g, AttrNamespace(item))
1760 return eval(expr, g, AttrNamespace(item))
1762
1761
1763 ok = 0
1762 ok = 0
1764 exc_info = None
1763 exc_info = None
1765 for item in xiter(self.input):
1764 for item in xiter(self.input):
1766 try:
1765 try:
1767 if test(item):
1766 if test(item):
1768 yield item
1767 yield item
1769 ok += 1
1768 ok += 1
1770 except (KeyboardInterrupt, SystemExit):
1769 except (KeyboardInterrupt, SystemExit):
1771 raise
1770 raise
1772 except Exception, exc:
1771 except Exception, exc:
1773 if self.errors == "drop":
1772 if self.errors == "drop":
1774 pass # Ignore errors
1773 pass # Ignore errors
1775 elif self.errors == "keep":
1774 elif self.errors == "keep":
1776 yield item
1775 yield item
1777 elif self.errors == "keeperror":
1776 elif self.errors == "keeperror":
1778 yield exc
1777 yield exc
1779 elif self.errors == "raise":
1778 elif self.errors == "raise":
1780 raise
1779 raise
1781 elif self.errors == "raiseifallfail":
1780 elif self.errors == "raiseifallfail":
1782 if exc_info is None:
1781 if exc_info is None:
1783 exc_info = sys.exc_info()
1782 exc_info = sys.exc_info()
1784 if not ok and exc_info is not None:
1783 if not ok and exc_info is not None:
1785 raise exc_info[0], exc_info[1], exc_info[2]
1784 raise exc_info[0], exc_info[1], exc_info[2]
1786
1785
1787 def __xrepr__(self, mode="default"):
1786 def __xrepr__(self, mode="default"):
1788 if mode == "header" or mode == "footer":
1787 if mode == "header" or mode == "footer":
1789 input = getattr(self, "input", None)
1788 input = getattr(self, "input", None)
1790 if input is not None:
1789 if input is not None:
1791 for part in xrepr(input, mode):
1790 for part in xrepr(input, mode):
1792 yield part
1791 yield part
1793 yield (astyle.style_default, " | ")
1792 yield (astyle.style_default, " | ")
1794 yield (astyle.style_default, "%s(" % self.__class__.__name__)
1793 yield (astyle.style_default, "%s(" % self.__class__.__name__)
1795 for part in xrepr(self.expr, "default"):
1794 for part in xrepr(self.expr, "default"):
1796 yield part
1795 yield part
1797 yield (astyle.style_default, ")")
1796 yield (astyle.style_default, ")")
1798 else:
1797 else:
1799 yield (astyle.style_default, repr(self))
1798 yield (astyle.style_default, repr(self))
1800
1799
1801 def __repr__(self):
1800 def __repr__(self):
1802 return "<%s.%s expr=%r at 0x%x>" % \
1801 return "<%s.%s expr=%r at 0x%x>" % \
1803 (self.__class__.__module__, self.__class__.__name__,
1802 (self.__class__.__module__, self.__class__.__name__,
1804 self.expr, id(self))
1803 self.expr, id(self))
1805
1804
1806
1805
1807 class ieval(Pipe):
1806 class ieval(Pipe):
1808 """
1807 """
1809 Evaluate an expression for each object in the input pipe.
1808 Evaluate an expression for each object in the input pipe.
1810
1809
1811 Examples::
1810 Examples::
1812
1811
1813 >>> ils | ieval("_.abspath()")
1812 py> ils | ieval("_.abspath()")
1814 >>> sys.path | ieval(ifile)
1813 py> sys.path | ieval(ifile)
1815 """
1814 """
1816
1815
1817 def __init__(self, expr, globals=None, errors="raiseifallfail"):
1816 def __init__(self, expr, globals=None, errors="raiseifallfail"):
1818 """
1817 """
1819 Create an ``ieval`` object. ``expr`` can be a callable or a string
1818 Create an ``ieval`` object. ``expr`` can be a callable or a string
1820 containing an expression. For the meaning of ``globals`` and
1819 containing an expression. For the meaning of ``globals`` and
1821 ``errors`` see ``ifilter``.
1820 ``errors`` see ``ifilter``.
1822 """
1821 """
1823 self.expr = expr
1822 self.expr = expr
1824 self.globals = globals
1823 self.globals = globals
1825 self.errors = errors
1824 self.errors = errors
1826
1825
1827 def __iter__(self):
1826 def __iter__(self):
1828 if callable(self.expr):
1827 if callable(self.expr):
1829 do = self.expr
1828 do = self.expr
1830 else:
1829 else:
1831 g = getglobals(self.globals)
1830 g = getglobals(self.globals)
1832 expr = compile(self.expr, "ipipe-expression", "eval")
1831 expr = compile(self.expr, "ipipe-expression", "eval")
1833 def do(item):
1832 def do(item):
1834 return eval(expr, g, AttrNamespace(item))
1833 return eval(expr, g, AttrNamespace(item))
1835
1834
1836 ok = 0
1835 ok = 0
1837 exc_info = None
1836 exc_info = None
1838 for item in xiter(self.input):
1837 for item in xiter(self.input):
1839 try:
1838 try:
1840 yield do(item)
1839 yield do(item)
1841 except (KeyboardInterrupt, SystemExit):
1840 except (KeyboardInterrupt, SystemExit):
1842 raise
1841 raise
1843 except Exception, exc:
1842 except Exception, exc:
1844 if self.errors == "drop":
1843 if self.errors == "drop":
1845 pass # Ignore errors
1844 pass # Ignore errors
1846 elif self.errors == "keep":
1845 elif self.errors == "keep":
1847 yield item
1846 yield item
1848 elif self.errors == "keeperror":
1847 elif self.errors == "keeperror":
1849 yield exc
1848 yield exc
1850 elif self.errors == "raise":
1849 elif self.errors == "raise":
1851 raise
1850 raise
1852 elif self.errors == "raiseifallfail":
1851 elif self.errors == "raiseifallfail":
1853 if exc_info is None:
1852 if exc_info is None:
1854 exc_info = sys.exc_info()
1853 exc_info = sys.exc_info()
1855 if not ok and exc_info is not None:
1854 if not ok and exc_info is not None:
1856 raise exc_info[0], exc_info[1], exc_info[2]
1855 raise exc_info[0], exc_info[1], exc_info[2]
1857
1856
1858 def __xrepr__(self, mode="default"):
1857 def __xrepr__(self, mode="default"):
1859 if mode == "header" or mode == "footer":
1858 if mode == "header" or mode == "footer":
1860 input = getattr(self, "input", None)
1859 input = getattr(self, "input", None)
1861 if input is not None:
1860 if input is not None:
1862 for part in xrepr(input, mode):
1861 for part in xrepr(input, mode):
1863 yield part
1862 yield part
1864 yield (astyle.style_default, " | ")
1863 yield (astyle.style_default, " | ")
1865 yield (astyle.style_default, "%s(" % self.__class__.__name__)
1864 yield (astyle.style_default, "%s(" % self.__class__.__name__)
1866 for part in xrepr(self.expr, "default"):
1865 for part in xrepr(self.expr, "default"):
1867 yield part
1866 yield part
1868 yield (astyle.style_default, ")")
1867 yield (astyle.style_default, ")")
1869 else:
1868 else:
1870 yield (astyle.style_default, repr(self))
1869 yield (astyle.style_default, repr(self))
1871
1870
1872 def __repr__(self):
1871 def __repr__(self):
1873 return "<%s.%s expr=%r at 0x%x>" % \
1872 return "<%s.%s expr=%r at 0x%x>" % \
1874 (self.__class__.__module__, self.__class__.__name__,
1873 (self.__class__.__module__, self.__class__.__name__,
1875 self.expr, id(self))
1874 self.expr, id(self))
1876
1875
1877
1876
1878 class ienum(Pipe):
1877 class ienum(Pipe):
1879 """
1878 """
1880 Enumerate the input pipe (i.e. wrap each input object in an object
1879 Enumerate the input pipe (i.e. wrap each input object in an object
1881 with ``index`` and ``object`` attributes).
1880 with ``index`` and ``object`` attributes).
1882
1881
1883 Examples::
1882 Examples::
1884
1883
1885 >>> xrange(20) | ieval("_,_*_") | ienum | ifilter("index % 2 == 0") | ieval("object")
1884 py> xrange(20) | ieval("_,_*_") | ienum | ifilter("index % 2 == 0") | ieval("object")
1886 """
1885 """
1887 def __iter__(self):
1886 def __iter__(self):
1888 fields = ("index", "object")
1887 fields = ("index", "object")
1889 for (index, object) in enumerate(xiter(self.input)):
1888 for (index, object) in enumerate(xiter(self.input)):
1890 yield Fields(fields, index=index, object=object)
1889 yield Fields(fields, index=index, object=object)
1891
1890
1892
1891
1893 class isort(Pipe):
1892 class isort(Pipe):
1894 """
1893 """
1895 Sorts the input pipe.
1894 Sorts the input pipe.
1896
1895
1897 Examples::
1896 Examples::
1898
1897
1899 >>> ils | isort("size")
1898 py> ils | isort("size")
1900 >>> ils | isort("_.isdir(), _.lower()", reverse=True)
1899 py> ils | isort("_.isdir(), _.lower()", reverse=True)
1901 """
1900 """
1902
1901
1903 def __init__(self, key=None, globals=None, reverse=False):
1902 def __init__(self, key=None, globals=None, reverse=False):
1904 """
1903 """
1905 Create an ``isort`` object. ``key`` can be a callable or a string
1904 Create an ``isort`` object. ``key`` can be a callable or a string
1906 containing an expression (or ``None`` in which case the items
1905 containing an expression (or ``None`` in which case the items
1907 themselves will be sorted). If ``reverse`` is true the sort order
1906 themselves will be sorted). If ``reverse`` is true the sort order
1908 will be reversed. For the meaning of ``globals`` see ``ifilter``.
1907 will be reversed. For the meaning of ``globals`` see ``ifilter``.
1909 """
1908 """
1910 self.key = key
1909 self.key = key
1911 self.globals = globals
1910 self.globals = globals
1912 self.reverse = reverse
1911 self.reverse = reverse
1913
1912
1914 def __iter__(self):
1913 def __iter__(self):
1915 if self.key is None:
1914 if self.key is None:
1916 items = sorted(xiter(self.input), reverse=self.reverse)
1915 items = sorted(xiter(self.input), reverse=self.reverse)
1917 elif callable(self.key):
1916 elif callable(self.key):
1918 items = sorted(xiter(self.input), key=self.key, reverse=self.reverse)
1917 items = sorted(xiter(self.input), key=self.key, reverse=self.reverse)
1919 else:
1918 else:
1920 g = getglobals(self.globals)
1919 g = getglobals(self.globals)
1921 key = compile(self.key, "ipipe-expression", "eval")
1920 key = compile(self.key, "ipipe-expression", "eval")
1922 def realkey(item):
1921 def realkey(item):
1923 return eval(key, g, AttrNamespace(item))
1922 return eval(key, g, AttrNamespace(item))
1924 items = sorted(xiter(self.input), key=realkey, reverse=self.reverse)
1923 items = sorted(xiter(self.input), key=realkey, reverse=self.reverse)
1925 for item in items:
1924 for item in items:
1926 yield item
1925 yield item
1927
1926
1928 def __xrepr__(self, mode="default"):
1927 def __xrepr__(self, mode="default"):
1929 if mode == "header" or mode == "footer":
1928 if mode == "header" or mode == "footer":
1930 input = getattr(self, "input", None)
1929 input = getattr(self, "input", None)
1931 if input is not None:
1930 if input is not None:
1932 for part in xrepr(input, mode):
1931 for part in xrepr(input, mode):
1933 yield part
1932 yield part
1934 yield (astyle.style_default, " | ")
1933 yield (astyle.style_default, " | ")
1935 yield (astyle.style_default, "%s(" % self.__class__.__name__)
1934 yield (astyle.style_default, "%s(" % self.__class__.__name__)
1936 for part in xrepr(self.key, "default"):
1935 for part in xrepr(self.key, "default"):
1937 yield part
1936 yield part
1938 if self.reverse:
1937 if self.reverse:
1939 yield (astyle.style_default, ", ")
1938 yield (astyle.style_default, ", ")
1940 for part in xrepr(True, "default"):
1939 for part in xrepr(True, "default"):
1941 yield part
1940 yield part
1942 yield (astyle.style_default, ")")
1941 yield (astyle.style_default, ")")
1943 else:
1942 else:
1944 yield (astyle.style_default, repr(self))
1943 yield (astyle.style_default, repr(self))
1945
1944
1946 def __repr__(self):
1945 def __repr__(self):
1947 return "<%s.%s key=%r reverse=%r at 0x%x>" % \
1946 return "<%s.%s key=%r reverse=%r at 0x%x>" % \
1948 (self.__class__.__module__, self.__class__.__name__,
1947 (self.__class__.__module__, self.__class__.__name__,
1949 self.key, self.reverse, id(self))
1948 self.key, self.reverse, id(self))
1950
1949
1951
1950
1952 tab = 3 # for expandtabs()
1951 tab = 3 # for expandtabs()
1953
1952
1954 def _format(field):
1953 def _format(field):
1955 if isinstance(field, str):
1954 if isinstance(field, str):
1956 text = repr(field.expandtabs(tab))[1:-1]
1955 text = repr(field.expandtabs(tab))[1:-1]
1957 elif isinstance(field, unicode):
1956 elif isinstance(field, unicode):
1958 text = repr(field.expandtabs(tab))[2:-1]
1957 text = repr(field.expandtabs(tab))[2:-1]
1959 elif isinstance(field, datetime.datetime):
1958 elif isinstance(field, datetime.datetime):
1960 # Don't use strftime() here, as this requires year >= 1900
1959 # Don't use strftime() here, as this requires year >= 1900
1961 text = "%04d-%02d-%02d %02d:%02d:%02d.%06d" % \
1960 text = "%04d-%02d-%02d %02d:%02d:%02d.%06d" % \
1962 (field.year, field.month, field.day,
1961 (field.year, field.month, field.day,
1963 field.hour, field.minute, field.second, field.microsecond)
1962 field.hour, field.minute, field.second, field.microsecond)
1964 elif isinstance(field, datetime.date):
1963 elif isinstance(field, datetime.date):
1965 text = "%04d-%02d-%02d" % (field.year, field.month, field.day)
1964 text = "%04d-%02d-%02d" % (field.year, field.month, field.day)
1966 else:
1965 else:
1967 text = repr(field)
1966 text = repr(field)
1968 return text
1967 return text
1969
1968
1970
1969
1971 class Display(object):
1970 class Display(object):
1972 class __metaclass__(type):
1971 class __metaclass__(type):
1973 def __ror__(self, input):
1972 def __ror__(self, input):
1974 return input | self()
1973 return input | self()
1975
1974
1976 def __init__(self, input=None):
1975 def __init__(self, input=None):
1977 self.input = input
1976 self.input = input
1978
1977
1979 def __ror__(self, input):
1978 def __ror__(self, input):
1980 self.input = input
1979 self.input = input
1981 return self
1980 return self
1982
1981
1983 def display(self):
1982 def display(self):
1984 pass
1983 pass
1985
1984
1986
1985
1987 class iless(Display):
1986 class iless(Display):
1988 cmd = "less --quit-if-one-screen --LONG-PROMPT --LINE-NUMBERS --chop-long-lines --shift=8 --RAW-CONTROL-CHARS"
1987 cmd = "less --quit-if-one-screen --LONG-PROMPT --LINE-NUMBERS --chop-long-lines --shift=8 --RAW-CONTROL-CHARS"
1989
1988
1990 def display(self):
1989 def display(self):
1991 try:
1990 try:
1992 pager = os.popen(self.cmd, "w")
1991 pager = os.popen(self.cmd, "w")
1993 try:
1992 try:
1994 for item in xiter(self.input):
1993 for item in xiter(self.input):
1995 first = False
1994 first = False
1996 for attr in xattrs(item, "default"):
1995 for attr in xattrs(item, "default"):
1997 if first:
1996 if first:
1998 first = False
1997 first = False
1999 else:
1998 else:
2000 pager.write(" ")
1999 pager.write(" ")
2001 attr = upgradexattr(attr)
2000 attr = upgradexattr(attr)
2002 if not isinstance(attr, SelfDescriptor):
2001 if not isinstance(attr, SelfDescriptor):
2003 pager.write(attr.name())
2002 pager.write(attr.name())
2004 pager.write("=")
2003 pager.write("=")
2005 pager.write(str(attr.value(item)))
2004 pager.write(str(attr.value(item)))
2006 pager.write("\n")
2005 pager.write("\n")
2007 finally:
2006 finally:
2008 pager.close()
2007 pager.close()
2009 except Exception, exc:
2008 except Exception, exc:
2010 print "%s: %s" % (exc.__class__.__name__, str(exc))
2009 print "%s: %s" % (exc.__class__.__name__, str(exc))
2011
2010
2012
2011
2013 class _RedirectIO(object):
2012 class _RedirectIO(object):
2014 def __init__(self,*args,**kwargs):
2013 def __init__(self,*args,**kwargs):
2015 """
2014 """
2016 Map the system output streams to self.
2015 Map the system output streams to self.
2017 """
2016 """
2018 self.stream = StringIO.StringIO()
2017 self.stream = StringIO.StringIO()
2019 self.stdout = sys.stdout
2018 self.stdout = sys.stdout
2020 sys.stdout = self
2019 sys.stdout = self
2021 self.stderr = sys.stderr
2020 self.stderr = sys.stderr
2022 sys.stderr = self
2021 sys.stderr = self
2023
2022
2024 def write(self, text):
2023 def write(self, text):
2025 """
2024 """
2026 Write both to screen and to self.
2025 Write both to screen and to self.
2027 """
2026 """
2028 self.stream.write(text)
2027 self.stream.write(text)
2029 self.stdout.write(text)
2028 self.stdout.write(text)
2030 if "\n" in text:
2029 if "\n" in text:
2031 self.stdout.flush()
2030 self.stdout.flush()
2032
2031
2033 def writelines(self, lines):
2032 def writelines(self, lines):
2034 """
2033 """
2035 Write lines both to screen and to self.
2034 Write lines both to screen and to self.
2036 """
2035 """
2037 self.stream.writelines(lines)
2036 self.stream.writelines(lines)
2038 self.stdout.writelines(lines)
2037 self.stdout.writelines(lines)
2039 self.stdout.flush()
2038 self.stdout.flush()
2040
2039
2041 def restore(self):
2040 def restore(self):
2042 """
2041 """
2043 Restore the default system streams.
2042 Restore the default system streams.
2044 """
2043 """
2045 self.stdout.flush()
2044 self.stdout.flush()
2046 self.stderr.flush()
2045 self.stderr.flush()
2047 sys.stdout = self.stdout
2046 sys.stdout = self.stdout
2048 sys.stderr = self.stderr
2047 sys.stderr = self.stderr
2049
2048
2050
2049
2051 class icap(Table):
2050 class icap(Table):
2052 """
2051 """
2053 Execute a python string and capture any output to stderr/stdout.
2052 Execute a python string and capture any output to stderr/stdout.
2054
2053
2055 Examples::
2054 Examples::
2056
2055
2057 >>> import time
2056 py> import time
2058 >>> icap("for i in range(10): print i, time.sleep(0.1)")
2057 py> icap("for i in range(10): print i, time.sleep(0.1)")
2059
2058
2060 """
2059 """
2061 def __init__(self, expr, globals=None):
2060 def __init__(self, expr, globals=None):
2062 self.expr = expr
2061 self.expr = expr
2063 self.globals = globals
2062 self.globals = globals
2064 log = _RedirectIO()
2063 log = _RedirectIO()
2065 try:
2064 try:
2066 exec(expr, getglobals(globals))
2065 exec(expr, getglobals(globals))
2067 finally:
2066 finally:
2068 log.restore()
2067 log.restore()
2069 self.stream = log.stream
2068 self.stream = log.stream
2070
2069
2071 def __iter__(self):
2070 def __iter__(self):
2072 self.stream.seek(0)
2071 self.stream.seek(0)
2073 for line in self.stream:
2072 for line in self.stream:
2074 yield line.rstrip("\r\n")
2073 yield line.rstrip("\r\n")
2075
2074
2076 def __xrepr__(self, mode="default"):
2075 def __xrepr__(self, mode="default"):
2077 if mode == "header" or mode == "footer":
2076 if mode == "header" or mode == "footer":
2078 yield (astyle.style_default,
2077 yield (astyle.style_default,
2079 "%s(%r)" % (self.__class__.__name__, self.expr))
2078 "%s(%r)" % (self.__class__.__name__, self.expr))
2080 else:
2079 else:
2081 yield (astyle.style_default, repr(self))
2080 yield (astyle.style_default, repr(self))
2082
2081
2083 def __repr__(self):
2082 def __repr__(self):
2084 return "%s.%s(%r)" % \
2083 return "%s.%s(%r)" % \
2085 (self.__class__.__module__, self.__class__.__name__, self.expr)
2084 (self.__class__.__module__, self.__class__.__name__, self.expr)
2086
2085
2087
2086
2088 def xformat(value, mode, maxlength):
2087 def xformat(value, mode, maxlength):
2089 align = None
2088 align = None
2090 full = True
2089 full = True
2091 width = 0
2090 width = 0
2092 text = astyle.Text()
2091 text = astyle.Text()
2093 for (style, part) in xrepr(value, mode):
2092 for (style, part) in xrepr(value, mode):
2094 # only consider the first result
2093 # only consider the first result
2095 if align is None:
2094 if align is None:
2096 if isinstance(style, int):
2095 if isinstance(style, int):
2097 # (style, text) really is (alignment, stop)
2096 # (style, text) really is (alignment, stop)
2098 align = style
2097 align = style
2099 full = part
2098 full = part
2100 continue
2099 continue
2101 else:
2100 else:
2102 align = -1
2101 align = -1
2103 full = True
2102 full = True
2104 if not isinstance(style, int):
2103 if not isinstance(style, int):
2105 text.append((style, part))
2104 text.append((style, part))
2106 width += len(part)
2105 width += len(part)
2107 if width >= maxlength and not full:
2106 if width >= maxlength and not full:
2108 text.append((astyle.style_ellisis, "..."))
2107 text.append((astyle.style_ellisis, "..."))
2109 width += 3
2108 width += 3
2110 break
2109 break
2111 if align is None: # default to left alignment
2110 if align is None: # default to left alignment
2112 align = -1
2111 align = -1
2113 return (align, width, text)
2112 return (align, width, text)
2114
2113
2115
2114
2116
2115
2117 import astyle
2116 import astyle
2118
2117
2119 class idump(Display):
2118 class idump(Display):
2120 # The approximate maximum length of a column entry
2119 # The approximate maximum length of a column entry
2121 maxattrlength = 200
2120 maxattrlength = 200
2122
2121
2123 # Style for column names
2122 # Style for column names
2124 style_header = astyle.Style.fromstr("white:black:bold")
2123 style_header = astyle.Style.fromstr("white:black:bold")
2125
2124
2126 def __init__(self, input=None, *attrs):
2125 def __init__(self, input=None, *attrs):
2127 Display.__init__(self, input)
2126 Display.__init__(self, input)
2128 self.attrs = [upgradexattr(attr) for attr in attrs]
2127 self.attrs = [upgradexattr(attr) for attr in attrs]
2129 self.headerpadchar = " "
2128 self.headerpadchar = " "
2130 self.headersepchar = "|"
2129 self.headersepchar = "|"
2131 self.datapadchar = " "
2130 self.datapadchar = " "
2132 self.datasepchar = "|"
2131 self.datasepchar = "|"
2133
2132
2134 def display(self):
2133 def display(self):
2135 stream = genutils.Term.cout
2134 stream = genutils.Term.cout
2136 allattrs = []
2135 allattrs = []
2137 attrset = set()
2136 attrset = set()
2138 colwidths = {}
2137 colwidths = {}
2139 rows = []
2138 rows = []
2140 for item in xiter(self.input):
2139 for item in xiter(self.input):
2141 row = {}
2140 row = {}
2142 attrs = self.attrs
2141 attrs = self.attrs
2143 if not attrs:
2142 if not attrs:
2144 attrs = xattrs(item, "default")
2143 attrs = xattrs(item, "default")
2145 for attr in attrs:
2144 for attr in attrs:
2146 if attr not in attrset:
2145 if attr not in attrset:
2147 allattrs.append(attr)
2146 allattrs.append(attr)
2148 attrset.add(attr)
2147 attrset.add(attr)
2149 colwidths[attr] = len(attr.name())
2148 colwidths[attr] = len(attr.name())
2150 try:
2149 try:
2151 value = attr.value(item)
2150 value = attr.value(item)
2152 except (KeyboardInterrupt, SystemExit):
2151 except (KeyboardInterrupt, SystemExit):
2153 raise
2152 raise
2154 except Exception, exc:
2153 except Exception, exc:
2155 value = exc
2154 value = exc
2156 (align, width, text) = xformat(value, "cell", self.maxattrlength)
2155 (align, width, text) = xformat(value, "cell", self.maxattrlength)
2157 colwidths[attr] = max(colwidths[attr], width)
2156 colwidths[attr] = max(colwidths[attr], width)
2158 # remember alignment, length and colored parts
2157 # remember alignment, length and colored parts
2159 row[attr] = (align, width, text)
2158 row[attr] = (align, width, text)
2160 rows.append(row)
2159 rows.append(row)
2161
2160
2162 stream.write("\n")
2161 stream.write("\n")
2163 for (i, attr) in enumerate(allattrs):
2162 for (i, attr) in enumerate(allattrs):
2164 attrname = attr.name()
2163 attrname = attr.name()
2165 self.style_header(attrname).write(stream)
2164 self.style_header(attrname).write(stream)
2166 spc = colwidths[attr] - len(attrname)
2165 spc = colwidths[attr] - len(attrname)
2167 if i < len(colwidths)-1:
2166 if i < len(colwidths)-1:
2168 stream.write(self.headerpadchar*spc)
2167 stream.write(self.headerpadchar*spc)
2169 stream.write(self.headersepchar)
2168 stream.write(self.headersepchar)
2170 stream.write("\n")
2169 stream.write("\n")
2171
2170
2172 for row in rows:
2171 for row in rows:
2173 for (i, attr) in enumerate(allattrs):
2172 for (i, attr) in enumerate(allattrs):
2174 (align, width, text) = row[attr]
2173 (align, width, text) = row[attr]
2175 spc = colwidths[attr] - width
2174 spc = colwidths[attr] - width
2176 if align == -1:
2175 if align == -1:
2177 text.write(stream)
2176 text.write(stream)
2178 if i < len(colwidths)-1:
2177 if i < len(colwidths)-1:
2179 stream.write(self.datapadchar*spc)
2178 stream.write(self.datapadchar*spc)
2180 elif align == 0:
2179 elif align == 0:
2181 spc = colwidths[attr] - width
2180 spc = colwidths[attr] - width
2182 spc1 = spc//2
2181 spc1 = spc//2
2183 spc2 = spc-spc1
2182 spc2 = spc-spc1
2184 stream.write(self.datapadchar*spc1)
2183 stream.write(self.datapadchar*spc1)
2185 text.write(stream)
2184 text.write(stream)
2186 if i < len(colwidths)-1:
2185 if i < len(colwidths)-1:
2187 stream.write(self.datapadchar*spc2)
2186 stream.write(self.datapadchar*spc2)
2188 else:
2187 else:
2189 stream.write(self.datapadchar*spc)
2188 stream.write(self.datapadchar*spc)
2190 text.write(stream)
2189 text.write(stream)
2191 if i < len(colwidths)-1:
2190 if i < len(colwidths)-1:
2192 stream.write(self.datasepchar)
2191 stream.write(self.datasepchar)
2193 stream.write("\n")
2192 stream.write("\n")
2194
2193
2195
2194
2196 class AttributeDetail(Table):
2195 class AttributeDetail(Table):
2197 """
2196 """
2198 ``AttributeDetail`` objects are use for displaying a detailed list of object
2197 ``AttributeDetail`` objects are use for displaying a detailed list of object
2199 attributes.
2198 attributes.
2200 """
2199 """
2201 def __init__(self, object, descriptor):
2200 def __init__(self, object, descriptor):
2202 self.object = object
2201 self.object = object
2203 self.descriptor = descriptor
2202 self.descriptor = descriptor
2204
2203
2205 def __iter__(self):
2204 def __iter__(self):
2206 return self.descriptor.iter(self.object)
2205 return self.descriptor.iter(self.object)
2207
2206
2208 def name(self):
2207 def name(self):
2209 return self.descriptor.name()
2208 return self.descriptor.name()
2210
2209
2211 def attrtype(self):
2210 def attrtype(self):
2212 return self.descriptor.attrtype(self.object)
2211 return self.descriptor.attrtype(self.object)
2213
2212
2214 def valuetype(self):
2213 def valuetype(self):
2215 return self.descriptor.valuetype(self.object)
2214 return self.descriptor.valuetype(self.object)
2216
2215
2217 def doc(self):
2216 def doc(self):
2218 return self.descriptor.doc(self.object)
2217 return self.descriptor.doc(self.object)
2219
2218
2220 def shortdoc(self):
2219 def shortdoc(self):
2221 return self.descriptor.shortdoc(self.object)
2220 return self.descriptor.shortdoc(self.object)
2222
2221
2223 def value(self):
2222 def value(self):
2224 return self.descriptor.value(self.object)
2223 return self.descriptor.value(self.object)
2225
2224
2226 def __xattrs__(self, mode="default"):
2225 def __xattrs__(self, mode="default"):
2227 attrs = ("name()", "attrtype()", "valuetype()", "value()", "shortdoc()")
2226 attrs = ("name()", "attrtype()", "valuetype()", "value()", "shortdoc()")
2228 if mode == "detail":
2227 if mode == "detail":
2229 attrs += ("doc()",)
2228 attrs += ("doc()",)
2230 return attrs
2229 return attrs
2231
2230
2232 def __xrepr__(self, mode="default"):
2231 def __xrepr__(self, mode="default"):
2233 yield (-1, True)
2232 yield (-1, True)
2234 valuetype = self.valuetype()
2233 valuetype = self.valuetype()
2235 if valuetype is not noitem:
2234 if valuetype is not noitem:
2236 for part in xrepr(valuetype):
2235 for part in xrepr(valuetype):
2237 yield part
2236 yield part
2238 yield (astyle.style_default, " ")
2237 yield (astyle.style_default, " ")
2239 yield (astyle.style_default, self.attrtype())
2238 yield (astyle.style_default, self.attrtype())
2240 yield (astyle.style_default, " ")
2239 yield (astyle.style_default, " ")
2241 yield (astyle.style_default, self.name())
2240 yield (astyle.style_default, self.name())
2242 yield (astyle.style_default, " of ")
2241 yield (astyle.style_default, " of ")
2243 for part in xrepr(self.object):
2242 for part in xrepr(self.object):
2244 yield part
2243 yield part
2245
2244
2246
2245
2247 try:
2246 try:
2248 from ibrowse import ibrowse
2247 from ibrowse import ibrowse
2249 except ImportError:
2248 except ImportError:
2250 # No curses (probably Windows) => try igrid
2249 # No curses (probably Windows) => try igrid
2251 try:
2250 try:
2252 from igrid import igrid
2251 from igrid import igrid
2253 except ImportError:
2252 except ImportError:
2254 # no wx either => use ``idump`` as the default display.
2253 # no wx either => use ``idump`` as the default display.
2255 defaultdisplay = idump
2254 defaultdisplay = idump
2256 else:
2255 else:
2257 defaultdisplay = igrid
2256 defaultdisplay = igrid
2258 __all__.append("igrid")
2257 __all__.append("igrid")
2259 else:
2258 else:
2260 defaultdisplay = ibrowse
2259 defaultdisplay = ibrowse
2261 __all__.append("ibrowse")
2260 __all__.append("ibrowse")
2262
2261
2263
2262
2264 # If we're running under IPython, register our objects with IPython's
2263 # If we're running under IPython, register our objects with IPython's
2265 # generic function ``result_display``, else install a displayhook
2264 # generic function ``result_display``, else install a displayhook
2266 # directly as sys.displayhook
2265 # directly as sys.displayhook
2267 if generics is not None:
2266 if generics is not None:
2268 def display_display(obj):
2267 def display_display(obj):
2269 return obj.display()
2268 return obj.display()
2270 generics.result_display.when_type(Display)(display_display)
2269 generics.result_display.when_type(Display)(display_display)
2271
2270
2272 def display_tableobject(obj):
2271 def display_tableobject(obj):
2273 return display_display(defaultdisplay(obj))
2272 return display_display(defaultdisplay(obj))
2274 generics.result_display.when_type(Table)(display_tableobject)
2273 generics.result_display.when_type(Table)(display_tableobject)
2275
2274
2276 def display_tableclass(obj):
2275 def display_tableclass(obj):
2277 return display_tableobject(obj())
2276 return display_tableobject(obj())
2278 generics.result_display.when_type(Table.__metaclass__)(display_tableclass)
2277 generics.result_display.when_type(Table.__metaclass__)(display_tableclass)
2279 else:
2278 else:
2280 def installdisplayhook():
2279 def installdisplayhook():
2281 _originalhook = sys.displayhook
2280 _originalhook = sys.displayhook
2282 def displayhook(obj):
2281 def displayhook(obj):
2283 if isinstance(obj, type) and issubclass(obj, Table):
2282 if isinstance(obj, type) and issubclass(obj, Table):
2284 obj = obj()
2283 obj = obj()
2285 if isinstance(obj, Table):
2284 if isinstance(obj, Table):
2286 obj = defaultdisplay(obj)
2285 obj = defaultdisplay(obj)
2287 if isinstance(obj, Display):
2286 if isinstance(obj, Display):
2288 return obj.display()
2287 return obj.display()
2289 else:
2288 else:
2290 _originalhook(obj)
2289 _originalhook(obj)
2291 sys.displayhook = displayhook
2290 sys.displayhook = displayhook
2292 installdisplayhook()
2291 installdisplayhook()
@@ -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,2118 +1,2132 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 General purpose utilities.
3 General purpose utilities.
4
4
5 This is a grab-bag of stuff I find useful in most programs I write. Some of
5 This is a grab-bag of stuff I find useful in most programs I write. Some of
6 these things are also convenient when working at the command line.
6 these things are also convenient when working at the command line.
7
7
8 $Id: genutils.py 2998 2008-01-31 10:06:04Z vivainio $"""
8 $Id: genutils.py 2998 2008-01-31 10:06:04Z vivainio $"""
9
9
10 #*****************************************************************************
10 #*****************************************************************************
11 # Copyright (C) 2001-2006 Fernando Perez. <fperez@colorado.edu>
11 # Copyright (C) 2001-2006 Fernando Perez. <fperez@colorado.edu>
12 #
12 #
13 # Distributed under the terms of the BSD License. The full license is in
13 # Distributed under the terms of the BSD License. The full license is in
14 # the file COPYING, distributed as part of this software.
14 # the file COPYING, distributed as part of this software.
15 #*****************************************************************************
15 #*****************************************************************************
16
16
17 from IPython import Release
17 from IPython import Release
18 __author__ = '%s <%s>' % Release.authors['Fernando']
18 __author__ = '%s <%s>' % Release.authors['Fernando']
19 __license__ = Release.license
19 __license__ = Release.license
20
20
21 #****************************************************************************
21 #****************************************************************************
22 # required modules from the Python standard library
22 # required modules from the Python standard library
23 import __main__
23 import __main__
24 import commands
24 import commands
25 try:
25 try:
26 import doctest
26 import doctest
27 except ImportError:
27 except ImportError:
28 pass
28 pass
29 import os
29 import os
30 import platform
30 import platform
31 import re
31 import re
32 import shlex
32 import shlex
33 import shutil
33 import shutil
34 import subprocess
34 import subprocess
35 import sys
35 import sys
36 import tempfile
36 import tempfile
37 import time
37 import time
38 import types
38 import types
39 import warnings
39 import warnings
40
40
41 # Curses and termios are Unix-only modules
41 # Curses and termios are Unix-only modules
42 try:
42 try:
43 import curses
43 import curses
44 # We need termios as well, so if its import happens to raise, we bail on
44 # We need termios as well, so if its import happens to raise, we bail on
45 # using curses altogether.
45 # using curses altogether.
46 import termios
46 import termios
47 except ImportError:
47 except ImportError:
48 USE_CURSES = False
48 USE_CURSES = False
49 else:
49 else:
50 # Curses on Solaris may not be complete, so we can't use it there
50 # Curses on Solaris may not be complete, so we can't use it there
51 USE_CURSES = hasattr(curses,'initscr')
51 USE_CURSES = hasattr(curses,'initscr')
52
52
53 # Other IPython utilities
53 # Other IPython utilities
54 import IPython
54 import IPython
55 from IPython.Itpl import Itpl,itpl,printpl
55 from IPython.Itpl import Itpl,itpl,printpl
56 from IPython import DPyGetOpt, platutils
56 from IPython import DPyGetOpt, platutils
57 from IPython.generics import result_display
57 from IPython.generics import result_display
58 import IPython.ipapi
58 import IPython.ipapi
59 from IPython.external.path import path
59 from IPython.external.path import path
60 if os.name == "nt":
60 if os.name == "nt":
61 from IPython.winconsole import get_console_size
61 from IPython.winconsole import get_console_size
62
62
63 try:
63 try:
64 set
64 set
65 except:
65 except:
66 from sets import Set as set
66 from sets import Set as set
67
67
68
68
69 #****************************************************************************
69 #****************************************************************************
70 # Exceptions
70 # Exceptions
71 class Error(Exception):
71 class Error(Exception):
72 """Base class for exceptions in this module."""
72 """Base class for exceptions in this module."""
73 pass
73 pass
74
74
75 #----------------------------------------------------------------------------
75 #----------------------------------------------------------------------------
76 class IOStream:
76 class IOStream:
77 def __init__(self,stream,fallback):
77 def __init__(self,stream,fallback):
78 if not hasattr(stream,'write') or not hasattr(stream,'flush'):
78 if not hasattr(stream,'write') or not hasattr(stream,'flush'):
79 stream = fallback
79 stream = fallback
80 self.stream = stream
80 self.stream = stream
81 self._swrite = stream.write
81 self._swrite = stream.write
82 self.flush = stream.flush
82 self.flush = stream.flush
83
83
84 def write(self,data):
84 def write(self,data):
85 try:
85 try:
86 self._swrite(data)
86 self._swrite(data)
87 except:
87 except:
88 try:
88 try:
89 # print handles some unicode issues which may trip a plain
89 # print handles some unicode issues which may trip a plain
90 # write() call. Attempt to emulate write() by using a
90 # write() call. Attempt to emulate write() by using a
91 # trailing comma
91 # trailing comma
92 print >> self.stream, data,
92 print >> self.stream, data,
93 except:
93 except:
94 # if we get here, something is seriously broken.
94 # if we get here, something is seriously broken.
95 print >> sys.stderr, \
95 print >> sys.stderr, \
96 'ERROR - failed to write data to stream:', self.stream
96 'ERROR - failed to write data to stream:', self.stream
97
97
98 def close(self):
98 def close(self):
99 pass
99 pass
100
100
101
101
102 class IOTerm:
102 class IOTerm:
103 """ Term holds the file or file-like objects for handling I/O operations.
103 """ Term holds the file or file-like objects for handling I/O operations.
104
104
105 These are normally just sys.stdin, sys.stdout and sys.stderr but for
105 These are normally just sys.stdin, sys.stdout and sys.stderr but for
106 Windows they can can replaced to allow editing the strings before they are
106 Windows they can can replaced to allow editing the strings before they are
107 displayed."""
107 displayed."""
108
108
109 # In the future, having IPython channel all its I/O operations through
109 # In the future, having IPython channel all its I/O operations through
110 # this class will make it easier to embed it into other environments which
110 # this class will make it easier to embed it into other environments which
111 # are not a normal terminal (such as a GUI-based shell)
111 # are not a normal terminal (such as a GUI-based shell)
112 def __init__(self,cin=None,cout=None,cerr=None):
112 def __init__(self,cin=None,cout=None,cerr=None):
113 self.cin = IOStream(cin,sys.stdin)
113 self.cin = IOStream(cin,sys.stdin)
114 self.cout = IOStream(cout,sys.stdout)
114 self.cout = IOStream(cout,sys.stdout)
115 self.cerr = IOStream(cerr,sys.stderr)
115 self.cerr = IOStream(cerr,sys.stderr)
116
116
117 # Global variable to be used for all I/O
117 # Global variable to be used for all I/O
118 Term = IOTerm()
118 Term = IOTerm()
119
119
120 import IPython.rlineimpl as readline
120 import IPython.rlineimpl as readline
121 # Remake Term to use the readline i/o facilities
121 # Remake Term to use the readline i/o facilities
122 if sys.platform == 'win32' and readline.have_readline:
122 if sys.platform == 'win32' and readline.have_readline:
123
123
124 Term = IOTerm(cout=readline._outputfile,cerr=readline._outputfile)
124 Term = IOTerm(cout=readline._outputfile,cerr=readline._outputfile)
125
125
126
126
127 #****************************************************************************
127 #****************************************************************************
128 # Generic warning/error printer, used by everything else
128 # Generic warning/error printer, used by everything else
129 def warn(msg,level=2,exit_val=1):
129 def warn(msg,level=2,exit_val=1):
130 """Standard warning printer. Gives formatting consistency.
130 """Standard warning printer. Gives formatting consistency.
131
131
132 Output is sent to Term.cerr (sys.stderr by default).
132 Output is sent to Term.cerr (sys.stderr by default).
133
133
134 Options:
134 Options:
135
135
136 -level(2): allows finer control:
136 -level(2): allows finer control:
137 0 -> Do nothing, dummy function.
137 0 -> Do nothing, dummy function.
138 1 -> Print message.
138 1 -> Print message.
139 2 -> Print 'WARNING:' + message. (Default level).
139 2 -> Print 'WARNING:' + message. (Default level).
140 3 -> Print 'ERROR:' + message.
140 3 -> Print 'ERROR:' + message.
141 4 -> Print 'FATAL ERROR:' + message and trigger a sys.exit(exit_val).
141 4 -> Print 'FATAL ERROR:' + message and trigger a sys.exit(exit_val).
142
142
143 -exit_val (1): exit value returned by sys.exit() for a level 4
143 -exit_val (1): exit value returned by sys.exit() for a level 4
144 warning. Ignored for all other levels."""
144 warning. Ignored for all other levels."""
145
145
146 if level>0:
146 if level>0:
147 header = ['','','WARNING: ','ERROR: ','FATAL ERROR: ']
147 header = ['','','WARNING: ','ERROR: ','FATAL ERROR: ']
148 print >> Term.cerr, '%s%s' % (header[level],msg)
148 print >> Term.cerr, '%s%s' % (header[level],msg)
149 if level == 4:
149 if level == 4:
150 print >> Term.cerr,'Exiting.\n'
150 print >> Term.cerr,'Exiting.\n'
151 sys.exit(exit_val)
151 sys.exit(exit_val)
152
152
153 def info(msg):
153 def info(msg):
154 """Equivalent to warn(msg,level=1)."""
154 """Equivalent to warn(msg,level=1)."""
155
155
156 warn(msg,level=1)
156 warn(msg,level=1)
157
157
158 def error(msg):
158 def error(msg):
159 """Equivalent to warn(msg,level=3)."""
159 """Equivalent to warn(msg,level=3)."""
160
160
161 warn(msg,level=3)
161 warn(msg,level=3)
162
162
163 def fatal(msg,exit_val=1):
163 def fatal(msg,exit_val=1):
164 """Equivalent to warn(msg,exit_val=exit_val,level=4)."""
164 """Equivalent to warn(msg,exit_val=exit_val,level=4)."""
165
165
166 warn(msg,exit_val=exit_val,level=4)
166 warn(msg,exit_val=exit_val,level=4)
167
167
168 #---------------------------------------------------------------------------
168 #---------------------------------------------------------------------------
169 # Debugging routines
169 # Debugging routines
170 #
170 #
171 def debugx(expr,pre_msg=''):
171 def debugx(expr,pre_msg=''):
172 """Print the value of an expression from the caller's frame.
172 """Print the value of an expression from the caller's frame.
173
173
174 Takes an expression, evaluates it in the caller's frame and prints both
174 Takes an expression, evaluates it in the caller's frame and prints both
175 the given expression and the resulting value (as well as a debug mark
175 the given expression and the resulting value (as well as a debug mark
176 indicating the name of the calling function. The input must be of a form
176 indicating the name of the calling function. The input must be of a form
177 suitable for eval().
177 suitable for eval().
178
178
179 An optional message can be passed, which will be prepended to the printed
179 An optional message can be passed, which will be prepended to the printed
180 expr->value pair."""
180 expr->value pair."""
181
181
182 cf = sys._getframe(1)
182 cf = sys._getframe(1)
183 print '[DBG:%s] %s%s -> %r' % (cf.f_code.co_name,pre_msg,expr,
183 print '[DBG:%s] %s%s -> %r' % (cf.f_code.co_name,pre_msg,expr,
184 eval(expr,cf.f_globals,cf.f_locals))
184 eval(expr,cf.f_globals,cf.f_locals))
185
185
186 # deactivate it by uncommenting the following line, which makes it a no-op
186 # deactivate it by uncommenting the following line, which makes it a no-op
187 #def debugx(expr,pre_msg=''): pass
187 #def debugx(expr,pre_msg=''): pass
188
188
189 #----------------------------------------------------------------------------
189 #----------------------------------------------------------------------------
190 StringTypes = types.StringTypes
190 StringTypes = types.StringTypes
191
191
192 # Basic timing functionality
192 # Basic timing functionality
193
193
194 # If possible (Unix), use the resource module instead of time.clock()
194 # If possible (Unix), use the resource module instead of time.clock()
195 try:
195 try:
196 import resource
196 import resource
197 def clocku():
197 def clocku():
198 """clocku() -> floating point number
198 """clocku() -> floating point number
199
199
200 Return the *USER* CPU time in seconds since the start of the process.
200 Return the *USER* CPU time in seconds since the start of the process.
201 This is done via a call to resource.getrusage, so it avoids the
201 This is done via a call to resource.getrusage, so it avoids the
202 wraparound problems in time.clock()."""
202 wraparound problems in time.clock()."""
203
203
204 return resource.getrusage(resource.RUSAGE_SELF)[0]
204 return resource.getrusage(resource.RUSAGE_SELF)[0]
205
205
206 def clocks():
206 def clocks():
207 """clocks() -> floating point number
207 """clocks() -> floating point number
208
208
209 Return the *SYSTEM* CPU time in seconds since the start of the process.
209 Return the *SYSTEM* CPU time in seconds since the start of the process.
210 This is done via a call to resource.getrusage, so it avoids the
210 This is done via a call to resource.getrusage, so it avoids the
211 wraparound problems in time.clock()."""
211 wraparound problems in time.clock()."""
212
212
213 return resource.getrusage(resource.RUSAGE_SELF)[1]
213 return resource.getrusage(resource.RUSAGE_SELF)[1]
214
214
215 def clock():
215 def clock():
216 """clock() -> floating point number
216 """clock() -> floating point number
217
217
218 Return the *TOTAL USER+SYSTEM* CPU time in seconds since the start of
218 Return the *TOTAL USER+SYSTEM* CPU time in seconds since the start of
219 the process. This is done via a call to resource.getrusage, so it
219 the process. This is done via a call to resource.getrusage, so it
220 avoids the wraparound problems in time.clock()."""
220 avoids the wraparound problems in time.clock()."""
221
221
222 u,s = resource.getrusage(resource.RUSAGE_SELF)[:2]
222 u,s = resource.getrusage(resource.RUSAGE_SELF)[:2]
223 return u+s
223 return u+s
224
224
225 def clock2():
225 def clock2():
226 """clock2() -> (t_user,t_system)
226 """clock2() -> (t_user,t_system)
227
227
228 Similar to clock(), but return a tuple of user/system times."""
228 Similar to clock(), but return a tuple of user/system times."""
229 return resource.getrusage(resource.RUSAGE_SELF)[:2]
229 return resource.getrusage(resource.RUSAGE_SELF)[:2]
230
230
231 except ImportError:
231 except ImportError:
232 # There is no distinction of user/system time under windows, so we just use
232 # There is no distinction of user/system time under windows, so we just use
233 # time.clock() for everything...
233 # time.clock() for everything...
234 clocku = clocks = clock = time.clock
234 clocku = clocks = clock = time.clock
235 def clock2():
235 def clock2():
236 """Under windows, system CPU time can't be measured.
236 """Under windows, system CPU time can't be measured.
237
237
238 This just returns clock() and zero."""
238 This just returns clock() and zero."""
239 return time.clock(),0.0
239 return time.clock(),0.0
240
240
241 def timings_out(reps,func,*args,**kw):
241 def timings_out(reps,func,*args,**kw):
242 """timings_out(reps,func,*args,**kw) -> (t_total,t_per_call,output)
242 """timings_out(reps,func,*args,**kw) -> (t_total,t_per_call,output)
243
243
244 Execute a function reps times, return a tuple with the elapsed total
244 Execute a function reps times, return a tuple with the elapsed total
245 CPU time in seconds, the time per call and the function's output.
245 CPU time in seconds, the time per call and the function's output.
246
246
247 Under Unix, the return value is the sum of user+system time consumed by
247 Under Unix, the return value is the sum of user+system time consumed by
248 the process, computed via the resource module. This prevents problems
248 the process, computed via the resource module. This prevents problems
249 related to the wraparound effect which the time.clock() function has.
249 related to the wraparound effect which the time.clock() function has.
250
250
251 Under Windows the return value is in wall clock seconds. See the
251 Under Windows the return value is in wall clock seconds. See the
252 documentation for the time module for more details."""
252 documentation for the time module for more details."""
253
253
254 reps = int(reps)
254 reps = int(reps)
255 assert reps >=1, 'reps must be >= 1'
255 assert reps >=1, 'reps must be >= 1'
256 if reps==1:
256 if reps==1:
257 start = clock()
257 start = clock()
258 out = func(*args,**kw)
258 out = func(*args,**kw)
259 tot_time = clock()-start
259 tot_time = clock()-start
260 else:
260 else:
261 rng = xrange(reps-1) # the last time is executed separately to store output
261 rng = xrange(reps-1) # the last time is executed separately to store output
262 start = clock()
262 start = clock()
263 for dummy in rng: func(*args,**kw)
263 for dummy in rng: func(*args,**kw)
264 out = func(*args,**kw) # one last time
264 out = func(*args,**kw) # one last time
265 tot_time = clock()-start
265 tot_time = clock()-start
266 av_time = tot_time / reps
266 av_time = tot_time / reps
267 return tot_time,av_time,out
267 return tot_time,av_time,out
268
268
269 def timings(reps,func,*args,**kw):
269 def timings(reps,func,*args,**kw):
270 """timings(reps,func,*args,**kw) -> (t_total,t_per_call)
270 """timings(reps,func,*args,**kw) -> (t_total,t_per_call)
271
271
272 Execute a function reps times, return a tuple with the elapsed total CPU
272 Execute a function reps times, return a tuple with the elapsed total CPU
273 time in seconds and the time per call. These are just the first two values
273 time in seconds and the time per call. These are just the first two values
274 in timings_out()."""
274 in timings_out()."""
275
275
276 return timings_out(reps,func,*args,**kw)[0:2]
276 return timings_out(reps,func,*args,**kw)[0:2]
277
277
278 def timing(func,*args,**kw):
278 def timing(func,*args,**kw):
279 """timing(func,*args,**kw) -> t_total
279 """timing(func,*args,**kw) -> t_total
280
280
281 Execute a function once, return the elapsed total CPU time in
281 Execute a function once, return the elapsed total CPU time in
282 seconds. This is just the first value in timings_out()."""
282 seconds. This is just the first value in timings_out()."""
283
283
284 return timings_out(1,func,*args,**kw)[0]
284 return timings_out(1,func,*args,**kw)[0]
285
285
286 #****************************************************************************
286 #****************************************************************************
287 # file and system
287 # file and system
288
288
289 def arg_split(s,posix=False):
289 def arg_split(s,posix=False):
290 """Split a command line's arguments in a shell-like manner.
290 """Split a command line's arguments in a shell-like manner.
291
291
292 This is a modified version of the standard library's shlex.split()
292 This is a modified version of the standard library's shlex.split()
293 function, but with a default of posix=False for splitting, so that quotes
293 function, but with a default of posix=False for splitting, so that quotes
294 in inputs are respected."""
294 in inputs are respected."""
295
295
296 # XXX - there may be unicode-related problems here!!! I'm not sure that
296 # XXX - there may be unicode-related problems here!!! I'm not sure that
297 # shlex is truly unicode-safe, so it might be necessary to do
297 # shlex is truly unicode-safe, so it might be necessary to do
298 #
298 #
299 # s = s.encode(sys.stdin.encoding)
299 # s = s.encode(sys.stdin.encoding)
300 #
300 #
301 # first, to ensure that shlex gets a normal string. Input from anyone who
301 # first, to ensure that shlex gets a normal string. Input from anyone who
302 # knows more about unicode and shlex than I would be good to have here...
302 # knows more about unicode and shlex than I would be good to have here...
303 lex = shlex.shlex(s, posix=posix)
303 lex = shlex.shlex(s, posix=posix)
304 lex.whitespace_split = True
304 lex.whitespace_split = True
305 return list(lex)
305 return list(lex)
306
306
307 def system(cmd,verbose=0,debug=0,header=''):
307 def system(cmd,verbose=0,debug=0,header=''):
308 """Execute a system command, return its exit status.
308 """Execute a system command, return its exit status.
309
309
310 Options:
310 Options:
311
311
312 - verbose (0): print the command to be executed.
312 - verbose (0): print the command to be executed.
313
313
314 - debug (0): only print, do not actually execute.
314 - debug (0): only print, do not actually execute.
315
315
316 - header (''): Header to print on screen prior to the executed command (it
316 - header (''): Header to print on screen prior to the executed command (it
317 is only prepended to the command, no newlines are added).
317 is only prepended to the command, no newlines are added).
318
318
319 Note: a stateful version of this function is available through the
319 Note: a stateful version of this function is available through the
320 SystemExec class."""
320 SystemExec class."""
321
321
322 stat = 0
322 stat = 0
323 if verbose or debug: print header+cmd
323 if verbose or debug: print header+cmd
324 sys.stdout.flush()
324 sys.stdout.flush()
325 if not debug: stat = os.system(cmd)
325 if not debug: stat = os.system(cmd)
326 return stat
326 return stat
327
327
328 def abbrev_cwd():
328 def abbrev_cwd():
329 """ Return abbreviated version of cwd, e.g. d:mydir """
329 """ Return abbreviated version of cwd, e.g. d:mydir """
330 cwd = os.getcwd().replace('\\','/')
330 cwd = os.getcwd().replace('\\','/')
331 drivepart = ''
331 drivepart = ''
332 tail = cwd
332 tail = cwd
333 if sys.platform == 'win32':
333 if sys.platform == 'win32':
334 if len(cwd) < 4:
334 if len(cwd) < 4:
335 return cwd
335 return cwd
336 drivepart,tail = os.path.splitdrive(cwd)
336 drivepart,tail = os.path.splitdrive(cwd)
337
338
337
339 parts = tail.split('/')
338
339 parts = tail.split('/')
340 if len(parts) > 2:
340 if len(parts) > 2:
341 tail = '/'.join(parts[-2:])
341 tail = '/'.join(parts[-2:])
342
342
343 return (drivepart + (
343 return (drivepart + (
344 cwd == '/' and '/' or tail))
344 cwd == '/' and '/' or tail))
345
345
346
346
347 # This function is used by ipython in a lot of places to make system calls.
347 # This function is used by ipython in a lot of places to make system calls.
348 # We need it to be slightly different under win32, due to the vagaries of
348 # We need it to be slightly different under win32, due to the vagaries of
349 # 'network shares'. A win32 override is below.
349 # 'network shares'. A win32 override is below.
350
350
351 def shell(cmd,verbose=0,debug=0,header=''):
351 def shell(cmd,verbose=0,debug=0,header=''):
352 """Execute a command in the system shell, always return None.
352 """Execute a command in the system shell, always return None.
353
353
354 Options:
354 Options:
355
355
356 - verbose (0): print the command to be executed.
356 - verbose (0): print the command to be executed.
357
357
358 - debug (0): only print, do not actually execute.
358 - debug (0): only print, do not actually execute.
359
359
360 - header (''): Header to print on screen prior to the executed command (it
360 - header (''): Header to print on screen prior to the executed command (it
361 is only prepended to the command, no newlines are added).
361 is only prepended to the command, no newlines are added).
362
362
363 Note: this is similar to genutils.system(), but it returns None so it can
363 Note: this is similar to genutils.system(), but it returns None so it can
364 be conveniently used in interactive loops without getting the return value
364 be conveniently used in interactive loops without getting the return value
365 (typically 0) printed many times."""
365 (typically 0) printed many times."""
366
366
367 stat = 0
367 stat = 0
368 if verbose or debug: print header+cmd
368 if verbose or debug: print header+cmd
369 # flush stdout so we don't mangle python's buffering
369 # flush stdout so we don't mangle python's buffering
370 sys.stdout.flush()
370 sys.stdout.flush()
371
371
372 if not debug:
372 if not debug:
373 platutils.set_term_title("IPy " + cmd)
373 platutils.set_term_title("IPy " + cmd)
374 os.system(cmd)
374 os.system(cmd)
375 platutils.set_term_title("IPy " + abbrev_cwd())
375 platutils.set_term_title("IPy " + abbrev_cwd())
376
376
377 # override shell() for win32 to deal with network shares
377 # override shell() for win32 to deal with network shares
378 if os.name in ('nt','dos'):
378 if os.name in ('nt','dos'):
379
379
380 shell_ori = shell
380 shell_ori = shell
381
381
382 def shell(cmd,verbose=0,debug=0,header=''):
382 def shell(cmd,verbose=0,debug=0,header=''):
383 if os.getcwd().startswith(r"\\"):
383 if os.getcwd().startswith(r"\\"):
384 path = os.getcwd()
384 path = os.getcwd()
385 # change to c drive (cannot be on UNC-share when issuing os.system,
385 # change to c drive (cannot be on UNC-share when issuing os.system,
386 # as cmd.exe cannot handle UNC addresses)
386 # as cmd.exe cannot handle UNC addresses)
387 os.chdir("c:")
387 os.chdir("c:")
388 # issue pushd to the UNC-share and then run the command
388 # issue pushd to the UNC-share and then run the command
389 try:
389 try:
390 shell_ori('"pushd %s&&"'%path+cmd,verbose,debug,header)
390 shell_ori('"pushd %s&&"'%path+cmd,verbose,debug,header)
391 finally:
391 finally:
392 os.chdir(path)
392 os.chdir(path)
393 else:
393 else:
394 shell_ori(cmd,verbose,debug,header)
394 shell_ori(cmd,verbose,debug,header)
395
395
396 shell.__doc__ = shell_ori.__doc__
396 shell.__doc__ = shell_ori.__doc__
397
397
398 def getoutput(cmd,verbose=0,debug=0,header='',split=0):
398 def getoutput(cmd,verbose=0,debug=0,header='',split=0):
399 """Dummy substitute for perl's backquotes.
399 """Dummy substitute for perl's backquotes.
400
400
401 Executes a command and returns the output.
401 Executes a command and returns the output.
402
402
403 Accepts the same arguments as system(), plus:
403 Accepts the same arguments as system(), plus:
404
404
405 - split(0): if true, the output is returned as a list split on newlines.
405 - split(0): if true, the output is returned as a list split on newlines.
406
406
407 Note: a stateful version of this function is available through the
407 Note: a stateful version of this function is available through the
408 SystemExec class.
408 SystemExec class.
409
409
410 This is pretty much deprecated and rarely used,
410 This is pretty much deprecated and rarely used,
411 genutils.getoutputerror may be what you need.
411 genutils.getoutputerror may be what you need.
412
412
413 """
413 """
414
414
415 if verbose or debug: print header+cmd
415 if verbose or debug: print header+cmd
416 if not debug:
416 if not debug:
417 output = os.popen(cmd).read()
417 output = os.popen(cmd).read()
418 # stipping last \n is here for backwards compat.
418 # stipping last \n is here for backwards compat.
419 if output.endswith('\n'):
419 if output.endswith('\n'):
420 output = output[:-1]
420 output = output[:-1]
421 if split:
421 if split:
422 return output.split('\n')
422 return output.split('\n')
423 else:
423 else:
424 return output
424 return output
425
425
426 def getoutputerror(cmd,verbose=0,debug=0,header='',split=0):
426 def getoutputerror(cmd,verbose=0,debug=0,header='',split=0):
427 """Return (standard output,standard error) of executing cmd in a shell.
427 """Return (standard output,standard error) of executing cmd in a shell.
428
428
429 Accepts the same arguments as system(), plus:
429 Accepts the same arguments as system(), plus:
430
430
431 - split(0): if true, each of stdout/err is returned as a list split on
431 - split(0): if true, each of stdout/err is returned as a list split on
432 newlines.
432 newlines.
433
433
434 Note: a stateful version of this function is available through the
434 Note: a stateful version of this function is available through the
435 SystemExec class."""
435 SystemExec class."""
436
436
437 if verbose or debug: print header+cmd
437 if verbose or debug: print header+cmd
438 if not cmd:
438 if not cmd:
439 if split:
439 if split:
440 return [],[]
440 return [],[]
441 else:
441 else:
442 return '',''
442 return '',''
443 if not debug:
443 if not debug:
444 pin,pout,perr = os.popen3(cmd)
444 pin,pout,perr = os.popen3(cmd)
445 tout = pout.read().rstrip()
445 tout = pout.read().rstrip()
446 terr = perr.read().rstrip()
446 terr = perr.read().rstrip()
447 pin.close()
447 pin.close()
448 pout.close()
448 pout.close()
449 perr.close()
449 perr.close()
450 if split:
450 if split:
451 return tout.split('\n'),terr.split('\n')
451 return tout.split('\n'),terr.split('\n')
452 else:
452 else:
453 return tout,terr
453 return tout,terr
454
454
455 # for compatibility with older naming conventions
455 # for compatibility with older naming conventions
456 xsys = system
456 xsys = system
457 bq = getoutput
457 bq = getoutput
458
458
459 class SystemExec:
459 class SystemExec:
460 """Access the system and getoutput functions through a stateful interface.
460 """Access the system and getoutput functions through a stateful interface.
461
461
462 Note: here we refer to the system and getoutput functions from this
462 Note: here we refer to the system and getoutput functions from this
463 library, not the ones from the standard python library.
463 library, not the ones from the standard python library.
464
464
465 This class offers the system and getoutput functions as methods, but the
465 This class offers the system and getoutput functions as methods, but the
466 verbose, debug and header parameters can be set for the instance (at
466 verbose, debug and header parameters can be set for the instance (at
467 creation time or later) so that they don't need to be specified on each
467 creation time or later) so that they don't need to be specified on each
468 call.
468 call.
469
469
470 For efficiency reasons, there's no way to override the parameters on a
470 For efficiency reasons, there's no way to override the parameters on a
471 per-call basis other than by setting instance attributes. If you need
471 per-call basis other than by setting instance attributes. If you need
472 local overrides, it's best to directly call system() or getoutput().
472 local overrides, it's best to directly call system() or getoutput().
473
473
474 The following names are provided as alternate options:
474 The following names are provided as alternate options:
475 - xsys: alias to system
475 - xsys: alias to system
476 - bq: alias to getoutput
476 - bq: alias to getoutput
477
477
478 An instance can then be created as:
478 An instance can then be created as:
479 >>> sysexec = SystemExec(verbose=1,debug=0,header='Calling: ')
479 >>> sysexec = SystemExec(verbose=1,debug=0,header='Calling: ')
480
481 And used as:
482 >>> sysexec.xsys('echo "Hello Python"')
483 Calling: echo "Hello Python"
484 Hello Python
485 """
480 """
486
481
487 def __init__(self,verbose=0,debug=0,header='',split=0):
482 def __init__(self,verbose=0,debug=0,header='',split=0):
488 """Specify the instance's values for verbose, debug and header."""
483 """Specify the instance's values for verbose, debug and header."""
489 setattr_list(self,'verbose debug header split')
484 setattr_list(self,'verbose debug header split')
490
485
491 def system(self,cmd):
486 def system(self,cmd):
492 """Stateful interface to system(), with the same keyword parameters."""
487 """Stateful interface to system(), with the same keyword parameters."""
493
488
494 system(cmd,self.verbose,self.debug,self.header)
489 system(cmd,self.verbose,self.debug,self.header)
495
490
496 def shell(self,cmd):
491 def shell(self,cmd):
497 """Stateful interface to shell(), with the same keyword parameters."""
492 """Stateful interface to shell(), with the same keyword parameters."""
498
493
499 shell(cmd,self.verbose,self.debug,self.header)
494 shell(cmd,self.verbose,self.debug,self.header)
500
495
501 xsys = system # alias
496 xsys = system # alias
502
497
503 def getoutput(self,cmd):
498 def getoutput(self,cmd):
504 """Stateful interface to getoutput()."""
499 """Stateful interface to getoutput()."""
505
500
506 return getoutput(cmd,self.verbose,self.debug,self.header,self.split)
501 return getoutput(cmd,self.verbose,self.debug,self.header,self.split)
507
502
508 def getoutputerror(self,cmd):
503 def getoutputerror(self,cmd):
509 """Stateful interface to getoutputerror()."""
504 """Stateful interface to getoutputerror()."""
510
505
511 return getoutputerror(cmd,self.verbose,self.debug,self.header,self.split)
506 return getoutputerror(cmd,self.verbose,self.debug,self.header,self.split)
512
507
513 bq = getoutput # alias
508 bq = getoutput # alias
514
509
515 #-----------------------------------------------------------------------------
510 #-----------------------------------------------------------------------------
516 def mutex_opts(dict,ex_op):
511 def mutex_opts(dict,ex_op):
517 """Check for presence of mutually exclusive keys in a dict.
512 """Check for presence of mutually exclusive keys in a dict.
518
513
519 Call: mutex_opts(dict,[[op1a,op1b],[op2a,op2b]...]"""
514 Call: mutex_opts(dict,[[op1a,op1b],[op2a,op2b]...]"""
520 for op1,op2 in ex_op:
515 for op1,op2 in ex_op:
521 if op1 in dict and op2 in dict:
516 if op1 in dict and op2 in dict:
522 raise ValueError,'\n*** ERROR in Arguments *** '\
517 raise ValueError,'\n*** ERROR in Arguments *** '\
523 'Options '+op1+' and '+op2+' are mutually exclusive.'
518 'Options '+op1+' and '+op2+' are mutually exclusive.'
524
519
525 #-----------------------------------------------------------------------------
520 #-----------------------------------------------------------------------------
526 def get_py_filename(name):
521 def get_py_filename(name):
527 """Return a valid python filename in the current directory.
522 """Return a valid python filename in the current directory.
528
523
529 If the given name is not a file, it adds '.py' and searches again.
524 If the given name is not a file, it adds '.py' and searches again.
530 Raises IOError with an informative message if the file isn't found."""
525 Raises IOError with an informative message if the file isn't found."""
531
526
532 name = os.path.expanduser(name)
527 name = os.path.expanduser(name)
533 if not os.path.isfile(name) and not name.endswith('.py'):
528 if not os.path.isfile(name) and not name.endswith('.py'):
534 name += '.py'
529 name += '.py'
535 if os.path.isfile(name):
530 if os.path.isfile(name):
536 return name
531 return name
537 else:
532 else:
538 raise IOError,'File `%s` not found.' % name
533 raise IOError,'File `%s` not found.' % name
539
534
540 #-----------------------------------------------------------------------------
535 #-----------------------------------------------------------------------------
541 def filefind(fname,alt_dirs = None):
536 def filefind(fname,alt_dirs = None):
542 """Return the given filename either in the current directory, if it
537 """Return the given filename either in the current directory, if it
543 exists, or in a specified list of directories.
538 exists, or in a specified list of directories.
544
539
545 ~ expansion is done on all file and directory names.
540 ~ expansion is done on all file and directory names.
546
541
547 Upon an unsuccessful search, raise an IOError exception."""
542 Upon an unsuccessful search, raise an IOError exception."""
548
543
549 if alt_dirs is None:
544 if alt_dirs is None:
550 try:
545 try:
551 alt_dirs = get_home_dir()
546 alt_dirs = get_home_dir()
552 except HomeDirError:
547 except HomeDirError:
553 alt_dirs = os.getcwd()
548 alt_dirs = os.getcwd()
554 search = [fname] + list_strings(alt_dirs)
549 search = [fname] + list_strings(alt_dirs)
555 search = map(os.path.expanduser,search)
550 search = map(os.path.expanduser,search)
556 #print 'search list for',fname,'list:',search # dbg
551 #print 'search list for',fname,'list:',search # dbg
557 fname = search[0]
552 fname = search[0]
558 if os.path.isfile(fname):
553 if os.path.isfile(fname):
559 return fname
554 return fname
560 for direc in search[1:]:
555 for direc in search[1:]:
561 testname = os.path.join(direc,fname)
556 testname = os.path.join(direc,fname)
562 #print 'testname',testname # dbg
557 #print 'testname',testname # dbg
563 if os.path.isfile(testname):
558 if os.path.isfile(testname):
564 return testname
559 return testname
565 raise IOError,'File' + `fname` + \
560 raise IOError,'File' + `fname` + \
566 ' not found in current or supplied directories:' + `alt_dirs`
561 ' not found in current or supplied directories:' + `alt_dirs`
567
562
568 #----------------------------------------------------------------------------
563 #----------------------------------------------------------------------------
569 def file_read(filename):
564 def file_read(filename):
570 """Read a file and close it. Returns the file source."""
565 """Read a file and close it. Returns the file source."""
571 fobj = open(filename,'r');
566 fobj = open(filename,'r');
572 source = fobj.read();
567 source = fobj.read();
573 fobj.close()
568 fobj.close()
574 return source
569 return source
575
570
576 def file_readlines(filename):
571 def file_readlines(filename):
577 """Read a file and close it. Returns the file source using readlines()."""
572 """Read a file and close it. Returns the file source using readlines()."""
578 fobj = open(filename,'r');
573 fobj = open(filename,'r');
579 lines = fobj.readlines();
574 lines = fobj.readlines();
580 fobj.close()
575 fobj.close()
581 return lines
576 return lines
582
577
583 #----------------------------------------------------------------------------
578 #----------------------------------------------------------------------------
584 def target_outdated(target,deps):
579 def target_outdated(target,deps):
585 """Determine whether a target is out of date.
580 """Determine whether a target is out of date.
586
581
587 target_outdated(target,deps) -> 1/0
582 target_outdated(target,deps) -> 1/0
588
583
589 deps: list of filenames which MUST exist.
584 deps: list of filenames which MUST exist.
590 target: single filename which may or may not exist.
585 target: single filename which may or may not exist.
591
586
592 If target doesn't exist or is older than any file listed in deps, return
587 If target doesn't exist or is older than any file listed in deps, return
593 true, otherwise return false.
588 true, otherwise return false.
594 """
589 """
595 try:
590 try:
596 target_time = os.path.getmtime(target)
591 target_time = os.path.getmtime(target)
597 except os.error:
592 except os.error:
598 return 1
593 return 1
599 for dep in deps:
594 for dep in deps:
600 dep_time = os.path.getmtime(dep)
595 dep_time = os.path.getmtime(dep)
601 if dep_time > target_time:
596 if dep_time > target_time:
602 #print "For target",target,"Dep failed:",dep # dbg
597 #print "For target",target,"Dep failed:",dep # dbg
603 #print "times (dep,tar):",dep_time,target_time # dbg
598 #print "times (dep,tar):",dep_time,target_time # dbg
604 return 1
599 return 1
605 return 0
600 return 0
606
601
607 #-----------------------------------------------------------------------------
602 #-----------------------------------------------------------------------------
608 def target_update(target,deps,cmd):
603 def target_update(target,deps,cmd):
609 """Update a target with a given command given a list of dependencies.
604 """Update a target with a given command given a list of dependencies.
610
605
611 target_update(target,deps,cmd) -> runs cmd if target is outdated.
606 target_update(target,deps,cmd) -> runs cmd if target is outdated.
612
607
613 This is just a wrapper around target_outdated() which calls the given
608 This is just a wrapper around target_outdated() which calls the given
614 command if target is outdated."""
609 command if target is outdated."""
615
610
616 if target_outdated(target,deps):
611 if target_outdated(target,deps):
617 xsys(cmd)
612 xsys(cmd)
618
613
619 #----------------------------------------------------------------------------
614 #----------------------------------------------------------------------------
620 def unquote_ends(istr):
615 def unquote_ends(istr):
621 """Remove a single pair of quotes from the endpoints of a string."""
616 """Remove a single pair of quotes from the endpoints of a string."""
622
617
623 if not istr:
618 if not istr:
624 return istr
619 return istr
625 if (istr[0]=="'" and istr[-1]=="'") or \
620 if (istr[0]=="'" and istr[-1]=="'") or \
626 (istr[0]=='"' and istr[-1]=='"'):
621 (istr[0]=='"' and istr[-1]=='"'):
627 return istr[1:-1]
622 return istr[1:-1]
628 else:
623 else:
629 return istr
624 return istr
630
625
631 #----------------------------------------------------------------------------
626 #----------------------------------------------------------------------------
632 def process_cmdline(argv,names=[],defaults={},usage=''):
627 def process_cmdline(argv,names=[],defaults={},usage=''):
633 """ Process command-line options and arguments.
628 """ Process command-line options and arguments.
634
629
635 Arguments:
630 Arguments:
636
631
637 - argv: list of arguments, typically sys.argv.
632 - argv: list of arguments, typically sys.argv.
638
633
639 - names: list of option names. See DPyGetOpt docs for details on options
634 - names: list of option names. See DPyGetOpt docs for details on options
640 syntax.
635 syntax.
641
636
642 - defaults: dict of default values.
637 - defaults: dict of default values.
643
638
644 - usage: optional usage notice to print if a wrong argument is passed.
639 - usage: optional usage notice to print if a wrong argument is passed.
645
640
646 Return a dict of options and a list of free arguments."""
641 Return a dict of options and a list of free arguments."""
647
642
648 getopt = DPyGetOpt.DPyGetOpt()
643 getopt = DPyGetOpt.DPyGetOpt()
649 getopt.setIgnoreCase(0)
644 getopt.setIgnoreCase(0)
650 getopt.parseConfiguration(names)
645 getopt.parseConfiguration(names)
651
646
652 try:
647 try:
653 getopt.processArguments(argv)
648 getopt.processArguments(argv)
654 except DPyGetOpt.ArgumentError, exc:
649 except DPyGetOpt.ArgumentError, exc:
655 print usage
650 print usage
656 warn('"%s"' % exc,level=4)
651 warn('"%s"' % exc,level=4)
657
652
658 defaults.update(getopt.optionValues)
653 defaults.update(getopt.optionValues)
659 args = getopt.freeValues
654 args = getopt.freeValues
660
655
661 return defaults,args
656 return defaults,args
662
657
663 #----------------------------------------------------------------------------
658 #----------------------------------------------------------------------------
664 def optstr2types(ostr):
659 def optstr2types(ostr):
665 """Convert a string of option names to a dict of type mappings.
660 """Convert a string of option names to a dict of type mappings.
666
661
667 optstr2types(str) -> {None:'string_opts',int:'int_opts',float:'float_opts'}
662 optstr2types(str) -> {None:'string_opts',int:'int_opts',float:'float_opts'}
668
663
669 This is used to get the types of all the options in a string formatted
664 This is used to get the types of all the options in a string formatted
670 with the conventions of DPyGetOpt. The 'type' None is used for options
665 with the conventions of DPyGetOpt. The 'type' None is used for options
671 which are strings (they need no further conversion). This function's main
666 which are strings (they need no further conversion). This function's main
672 use is to get a typemap for use with read_dict().
667 use is to get a typemap for use with read_dict().
673 """
668 """
674
669
675 typeconv = {None:'',int:'',float:''}
670 typeconv = {None:'',int:'',float:''}
676 typemap = {'s':None,'i':int,'f':float}
671 typemap = {'s':None,'i':int,'f':float}
677 opt_re = re.compile(r'([\w]*)([^:=]*:?=?)([sif]?)')
672 opt_re = re.compile(r'([\w]*)([^:=]*:?=?)([sif]?)')
678
673
679 for w in ostr.split():
674 for w in ostr.split():
680 oname,alias,otype = opt_re.match(w).groups()
675 oname,alias,otype = opt_re.match(w).groups()
681 if otype == '' or alias == '!': # simple switches are integers too
676 if otype == '' or alias == '!': # simple switches are integers too
682 otype = 'i'
677 otype = 'i'
683 typeconv[typemap[otype]] += oname + ' '
678 typeconv[typemap[otype]] += oname + ' '
684 return typeconv
679 return typeconv
685
680
686 #----------------------------------------------------------------------------
681 #----------------------------------------------------------------------------
687 def read_dict(filename,type_conv=None,**opt):
682 def read_dict(filename,type_conv=None,**opt):
688 """Read a dictionary of key=value pairs from an input file, optionally
683 r"""Read a dictionary of key=value pairs from an input file, optionally
689 performing conversions on the resulting values.
684 performing conversions on the resulting values.
690
685
691 read_dict(filename,type_conv,**opt) -> dict
686 read_dict(filename,type_conv,**opt) -> dict
692
687
693 Only one value per line is accepted, the format should be
688 Only one value per line is accepted, the format should be
694 # optional comments are ignored
689 # optional comments are ignored
695 key value\n
690 key value\n
696
691
697 Args:
692 Args:
698
693
699 - type_conv: A dictionary specifying which keys need to be converted to
694 - type_conv: A dictionary specifying which keys need to be converted to
700 which types. By default all keys are read as strings. This dictionary
695 which types. By default all keys are read as strings. This dictionary
701 should have as its keys valid conversion functions for strings
696 should have as its keys valid conversion functions for strings
702 (int,long,float,complex, or your own). The value for each key
697 (int,long,float,complex, or your own). The value for each key
703 (converter) should be a whitespace separated string containing the names
698 (converter) should be a whitespace separated string containing the names
704 of all the entries in the file to be converted using that function. For
699 of all the entries in the file to be converted using that function. For
705 keys to be left alone, use None as the conversion function (only needed
700 keys to be left alone, use None as the conversion function (only needed
706 with purge=1, see below).
701 with purge=1, see below).
707
702
708 - opt: dictionary with extra options as below (default in parens)
703 - opt: dictionary with extra options as below (default in parens)
709
704
710 purge(0): if set to 1, all keys *not* listed in type_conv are purged out
705 purge(0): if set to 1, all keys *not* listed in type_conv are purged out
711 of the dictionary to be returned. If purge is going to be used, the
706 of the dictionary to be returned. If purge is going to be used, the
712 set of keys to be left as strings also has to be explicitly specified
707 set of keys to be left as strings also has to be explicitly specified
713 using the (non-existent) conversion function None.
708 using the (non-existent) conversion function None.
714
709
715 fs(None): field separator. This is the key/value separator to be used
710 fs(None): field separator. This is the key/value separator to be used
716 when parsing the file. The None default means any whitespace [behavior
711 when parsing the file. The None default means any whitespace [behavior
717 of string.split()].
712 of string.split()].
718
713
719 strip(0): if 1, strip string values of leading/trailinig whitespace.
714 strip(0): if 1, strip string values of leading/trailinig whitespace.
720
715
721 warn(1): warning level if requested keys are not found in file.
716 warn(1): warning level if requested keys are not found in file.
722 - 0: silently ignore.
717 - 0: silently ignore.
723 - 1: inform but proceed.
718 - 1: inform but proceed.
724 - 2: raise KeyError exception.
719 - 2: raise KeyError exception.
725
720
726 no_empty(0): if 1, remove keys with whitespace strings as a value.
721 no_empty(0): if 1, remove keys with whitespace strings as a value.
727
722
728 unique([]): list of keys (or space separated string) which can't be
723 unique([]): list of keys (or space separated string) which can't be
729 repeated. If one such key is found in the file, each new instance
724 repeated. If one such key is found in the file, each new instance
730 overwrites the previous one. For keys not listed here, the behavior is
725 overwrites the previous one. For keys not listed here, the behavior is
731 to make a list of all appearances.
726 to make a list of all appearances.
732
727
733 Example:
728 Example:
734 If the input file test.ini has:
735 i 3
736 x 4.5
737 y 5.5
738 s hi ho
739 Then:
740
729
730 If the input file test.ini contains (we put it in a string to keep the test
731 self-contained):
732
733 >>> test_ini = '''\
734 ... i 3
735 ... x 4.5
736 ... y 5.5
737 ... s hi ho'''
738
739 Then we can use it as follows:
741 >>> type_conv={int:'i',float:'x',None:'s'}
740 >>> type_conv={int:'i',float:'x',None:'s'}
742 >>> read_dict('test.ini')
741
743 {'i': '3', 's': 'hi ho', 'x': '4.5', 'y': '5.5'}
742 >>> d = read_dict(test_ini)
744 >>> read_dict('test.ini',type_conv)
743
745 {'i': 3, 's': 'hi ho', 'x': 4.5, 'y': '5.5'}
744 >>> sorted(d.items())
746 >>> read_dict('test.ini',type_conv,purge=1)
745 [('i', '3'), ('s', 'hi ho'), ('x', '4.5'), ('y', '5.5')]
747 {'i': 3, 's': 'hi ho', 'x': 4.5}
746
747 >>> d = read_dict(test_ini,type_conv)
748
749 >>> sorted(d.items())
750 [('i', 3), ('s', 'hi ho'), ('x', 4.5), ('y', '5.5')]
751
752 >>> d = read_dict(test_ini,type_conv,purge=True)
753
754 >>> sorted(d.items())
755 [('i', 3), ('s', 'hi ho'), ('x', 4.5)]
748 """
756 """
749
757
750 # starting config
758 # starting config
751 opt.setdefault('purge',0)
759 opt.setdefault('purge',0)
752 opt.setdefault('fs',None) # field sep defaults to any whitespace
760 opt.setdefault('fs',None) # field sep defaults to any whitespace
753 opt.setdefault('strip',0)
761 opt.setdefault('strip',0)
754 opt.setdefault('warn',1)
762 opt.setdefault('warn',1)
755 opt.setdefault('no_empty',0)
763 opt.setdefault('no_empty',0)
756 opt.setdefault('unique','')
764 opt.setdefault('unique','')
757 if type(opt['unique']) in StringTypes:
765 if type(opt['unique']) in StringTypes:
758 unique_keys = qw(opt['unique'])
766 unique_keys = qw(opt['unique'])
759 elif type(opt['unique']) in (types.TupleType,types.ListType):
767 elif type(opt['unique']) in (types.TupleType,types.ListType):
760 unique_keys = opt['unique']
768 unique_keys = opt['unique']
761 else:
769 else:
762 raise ValueError, 'Unique keys must be given as a string, List or Tuple'
770 raise ValueError, 'Unique keys must be given as a string, List or Tuple'
763
771
764 dict = {}
772 dict = {}
773
765 # first read in table of values as strings
774 # first read in table of values as strings
766 file = open(filename,'r')
775 if '\n' in filename:
767 for line in file.readlines():
776 lines = filename.splitlines()
777 file = None
778 else:
779 file = open(filename,'r')
780 lines = file.readlines()
781 for line in lines:
768 line = line.strip()
782 line = line.strip()
769 if len(line) and line[0]=='#': continue
783 if len(line) and line[0]=='#': continue
770 if len(line)>0:
784 if len(line)>0:
771 lsplit = line.split(opt['fs'],1)
785 lsplit = line.split(opt['fs'],1)
772 try:
786 try:
773 key,val = lsplit
787 key,val = lsplit
774 except ValueError:
788 except ValueError:
775 key,val = lsplit[0],''
789 key,val = lsplit[0],''
776 key = key.strip()
790 key = key.strip()
777 if opt['strip']: val = val.strip()
791 if opt['strip']: val = val.strip()
778 if val == "''" or val == '""': val = ''
792 if val == "''" or val == '""': val = ''
779 if opt['no_empty'] and (val=='' or val.isspace()):
793 if opt['no_empty'] and (val=='' or val.isspace()):
780 continue
794 continue
781 # if a key is found more than once in the file, build a list
795 # if a key is found more than once in the file, build a list
782 # unless it's in the 'unique' list. In that case, last found in file
796 # unless it's in the 'unique' list. In that case, last found in file
783 # takes precedence. User beware.
797 # takes precedence. User beware.
784 try:
798 try:
785 if dict[key] and key in unique_keys:
799 if dict[key] and key in unique_keys:
786 dict[key] = val
800 dict[key] = val
787 elif type(dict[key]) is types.ListType:
801 elif type(dict[key]) is types.ListType:
788 dict[key].append(val)
802 dict[key].append(val)
789 else:
803 else:
790 dict[key] = [dict[key],val]
804 dict[key] = [dict[key],val]
791 except KeyError:
805 except KeyError:
792 dict[key] = val
806 dict[key] = val
793 # purge if requested
807 # purge if requested
794 if opt['purge']:
808 if opt['purge']:
795 accepted_keys = qwflat(type_conv.values())
809 accepted_keys = qwflat(type_conv.values())
796 for key in dict.keys():
810 for key in dict.keys():
797 if key in accepted_keys: continue
811 if key in accepted_keys: continue
798 del(dict[key])
812 del(dict[key])
799 # now convert if requested
813 # now convert if requested
800 if type_conv==None: return dict
814 if type_conv==None: return dict
801 conversions = type_conv.keys()
815 conversions = type_conv.keys()
802 try: conversions.remove(None)
816 try: conversions.remove(None)
803 except: pass
817 except: pass
804 for convert in conversions:
818 for convert in conversions:
805 for val in qw(type_conv[convert]):
819 for val in qw(type_conv[convert]):
806 try:
820 try:
807 dict[val] = convert(dict[val])
821 dict[val] = convert(dict[val])
808 except KeyError,e:
822 except KeyError,e:
809 if opt['warn'] == 0:
823 if opt['warn'] == 0:
810 pass
824 pass
811 elif opt['warn'] == 1:
825 elif opt['warn'] == 1:
812 print >>sys.stderr, 'Warning: key',val,\
826 print >>sys.stderr, 'Warning: key',val,\
813 'not found in file',filename
827 'not found in file',filename
814 elif opt['warn'] == 2:
828 elif opt['warn'] == 2:
815 raise KeyError,e
829 raise KeyError,e
816 else:
830 else:
817 raise ValueError,'Warning level must be 0,1 or 2'
831 raise ValueError,'Warning level must be 0,1 or 2'
818
832
819 return dict
833 return dict
820
834
821 #----------------------------------------------------------------------------
835 #----------------------------------------------------------------------------
822 def flag_calls(func):
836 def flag_calls(func):
823 """Wrap a function to detect and flag when it gets called.
837 """Wrap a function to detect and flag when it gets called.
824
838
825 This is a decorator which takes a function and wraps it in a function with
839 This is a decorator which takes a function and wraps it in a function with
826 a 'called' attribute. wrapper.called is initialized to False.
840 a 'called' attribute. wrapper.called is initialized to False.
827
841
828 The wrapper.called attribute is set to False right before each call to the
842 The wrapper.called attribute is set to False right before each call to the
829 wrapped function, so if the call fails it remains False. After the call
843 wrapped function, so if the call fails it remains False. After the call
830 completes, wrapper.called is set to True and the output is returned.
844 completes, wrapper.called is set to True and the output is returned.
831
845
832 Testing for truth in wrapper.called allows you to determine if a call to
846 Testing for truth in wrapper.called allows you to determine if a call to
833 func() was attempted and succeeded."""
847 func() was attempted and succeeded."""
834
848
835 def wrapper(*args,**kw):
849 def wrapper(*args,**kw):
836 wrapper.called = False
850 wrapper.called = False
837 out = func(*args,**kw)
851 out = func(*args,**kw)
838 wrapper.called = True
852 wrapper.called = True
839 return out
853 return out
840
854
841 wrapper.called = False
855 wrapper.called = False
842 wrapper.__doc__ = func.__doc__
856 wrapper.__doc__ = func.__doc__
843 return wrapper
857 return wrapper
844
858
845 #----------------------------------------------------------------------------
859 #----------------------------------------------------------------------------
846 def dhook_wrap(func,*a,**k):
860 def dhook_wrap(func,*a,**k):
847 """Wrap a function call in a sys.displayhook controller.
861 """Wrap a function call in a sys.displayhook controller.
848
862
849 Returns a wrapper around func which calls func, with all its arguments and
863 Returns a wrapper around func which calls func, with all its arguments and
850 keywords unmodified, using the default sys.displayhook. Since IPython
864 keywords unmodified, using the default sys.displayhook. Since IPython
851 modifies sys.displayhook, it breaks the behavior of certain systems that
865 modifies sys.displayhook, it breaks the behavior of certain systems that
852 rely on the default behavior, notably doctest.
866 rely on the default behavior, notably doctest.
853 """
867 """
854
868
855 def f(*a,**k):
869 def f(*a,**k):
856
870
857 dhook_s = sys.displayhook
871 dhook_s = sys.displayhook
858 sys.displayhook = sys.__displayhook__
872 sys.displayhook = sys.__displayhook__
859 try:
873 try:
860 out = func(*a,**k)
874 out = func(*a,**k)
861 finally:
875 finally:
862 sys.displayhook = dhook_s
876 sys.displayhook = dhook_s
863
877
864 return out
878 return out
865
879
866 f.__doc__ = func.__doc__
880 f.__doc__ = func.__doc__
867 return f
881 return f
868
882
869 #----------------------------------------------------------------------------
883 #----------------------------------------------------------------------------
870 def doctest_reload():
884 def doctest_reload():
871 """Properly reload doctest to reuse it interactively.
885 """Properly reload doctest to reuse it interactively.
872
886
873 This routine:
887 This routine:
874
888
875 - reloads doctest
889 - reloads doctest
876
890
877 - resets its global 'master' attribute to None, so that multiple uses of
891 - resets its global 'master' attribute to None, so that multiple uses of
878 the module interactively don't produce cumulative reports.
892 the module interactively don't produce cumulative reports.
879
893
880 - Monkeypatches its core test runner method to protect it from IPython's
894 - Monkeypatches its core test runner method to protect it from IPython's
881 modified displayhook. Doctest expects the default displayhook behavior
895 modified displayhook. Doctest expects the default displayhook behavior
882 deep down, so our modification breaks it completely. For this reason, a
896 deep down, so our modification breaks it completely. For this reason, a
883 hard monkeypatch seems like a reasonable solution rather than asking
897 hard monkeypatch seems like a reasonable solution rather than asking
884 users to manually use a different doctest runner when under IPython."""
898 users to manually use a different doctest runner when under IPython."""
885
899
886 import doctest
900 import doctest
887 reload(doctest)
901 reload(doctest)
888 doctest.master=None
902 doctest.master=None
889
903
890 try:
904 try:
891 doctest.DocTestRunner
905 doctest.DocTestRunner
892 except AttributeError:
906 except AttributeError:
893 # This is only for python 2.3 compatibility, remove once we move to
907 # This is only for python 2.3 compatibility, remove once we move to
894 # 2.4 only.
908 # 2.4 only.
895 pass
909 pass
896 else:
910 else:
897 doctest.DocTestRunner.run = dhook_wrap(doctest.DocTestRunner.run)
911 doctest.DocTestRunner.run = dhook_wrap(doctest.DocTestRunner.run)
898
912
899 #----------------------------------------------------------------------------
913 #----------------------------------------------------------------------------
900 class HomeDirError(Error):
914 class HomeDirError(Error):
901 pass
915 pass
902
916
903 def get_home_dir():
917 def get_home_dir():
904 """Return the closest possible equivalent to a 'home' directory.
918 """Return the closest possible equivalent to a 'home' directory.
905
919
906 We first try $HOME. Absent that, on NT it's $HOMEDRIVE\$HOMEPATH.
920 We first try $HOME. Absent that, on NT it's $HOMEDRIVE\$HOMEPATH.
907
921
908 Currently only Posix and NT are implemented, a HomeDirError exception is
922 Currently only Posix and NT are implemented, a HomeDirError exception is
909 raised for all other OSes. """
923 raised for all other OSes. """
910
924
911 isdir = os.path.isdir
925 isdir = os.path.isdir
912 env = os.environ
926 env = os.environ
913
927
914 # first, check py2exe distribution root directory for _ipython.
928 # first, check py2exe distribution root directory for _ipython.
915 # This overrides all. Normally does not exist.
929 # This overrides all. Normally does not exist.
916
930
917 if '\\library.zip\\' in IPython.__file__.lower():
931 if '\\library.zip\\' in IPython.__file__.lower():
918 root, rest = IPython.__file__.lower().split('library.zip')
932 root, rest = IPython.__file__.lower().split('library.zip')
919 if isdir(root + '_ipython'):
933 if isdir(root + '_ipython'):
920 os.environ["IPYKITROOT"] = root.rstrip('\\')
934 os.environ["IPYKITROOT"] = root.rstrip('\\')
921 return root
935 return root
922
936
923 try:
937 try:
924 homedir = env['HOME']
938 homedir = env['HOME']
925 if not isdir(homedir):
939 if not isdir(homedir):
926 # in case a user stuck some string which does NOT resolve to a
940 # in case a user stuck some string which does NOT resolve to a
927 # valid path, it's as good as if we hadn't foud it
941 # valid path, it's as good as if we hadn't foud it
928 raise KeyError
942 raise KeyError
929 return homedir
943 return homedir
930 except KeyError:
944 except KeyError:
931 if os.name == 'posix':
945 if os.name == 'posix':
932 raise HomeDirError,'undefined $HOME, IPython can not proceed.'
946 raise HomeDirError,'undefined $HOME, IPython can not proceed.'
933 elif os.name == 'nt':
947 elif os.name == 'nt':
934 # For some strange reason, win9x returns 'nt' for os.name.
948 # For some strange reason, win9x returns 'nt' for os.name.
935 try:
949 try:
936 homedir = os.path.join(env['HOMEDRIVE'],env['HOMEPATH'])
950 homedir = os.path.join(env['HOMEDRIVE'],env['HOMEPATH'])
937 if not isdir(homedir):
951 if not isdir(homedir):
938 homedir = os.path.join(env['USERPROFILE'])
952 homedir = os.path.join(env['USERPROFILE'])
939 if not isdir(homedir):
953 if not isdir(homedir):
940 raise HomeDirError
954 raise HomeDirError
941 return homedir
955 return homedir
942 except:
956 except:
943 try:
957 try:
944 # Use the registry to get the 'My Documents' folder.
958 # Use the registry to get the 'My Documents' folder.
945 import _winreg as wreg
959 import _winreg as wreg
946 key = wreg.OpenKey(wreg.HKEY_CURRENT_USER,
960 key = wreg.OpenKey(wreg.HKEY_CURRENT_USER,
947 "Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders")
961 "Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders")
948 homedir = wreg.QueryValueEx(key,'Personal')[0]
962 homedir = wreg.QueryValueEx(key,'Personal')[0]
949 key.Close()
963 key.Close()
950 if not isdir(homedir):
964 if not isdir(homedir):
951 e = ('Invalid "Personal" folder registry key '
965 e = ('Invalid "Personal" folder registry key '
952 'typically "My Documents".\n'
966 'typically "My Documents".\n'
953 'Value: %s\n'
967 'Value: %s\n'
954 'This is not a valid directory on your system.' %
968 'This is not a valid directory on your system.' %
955 homedir)
969 homedir)
956 raise HomeDirError(e)
970 raise HomeDirError(e)
957 return homedir
971 return homedir
958 except HomeDirError:
972 except HomeDirError:
959 raise
973 raise
960 except:
974 except:
961 return 'C:\\'
975 return 'C:\\'
962 elif os.name == 'dos':
976 elif os.name == 'dos':
963 # Desperate, may do absurd things in classic MacOS. May work under DOS.
977 # Desperate, may do absurd things in classic MacOS. May work under DOS.
964 return 'C:\\'
978 return 'C:\\'
965 else:
979 else:
966 raise HomeDirError,'support for your operating system not implemented.'
980 raise HomeDirError,'support for your operating system not implemented.'
967
981
968 #****************************************************************************
982 #****************************************************************************
969 # strings and text
983 # strings and text
970
984
971 class LSString(str):
985 class LSString(str):
972 """String derivative with a special access attributes.
986 """String derivative with a special access attributes.
973
987
974 These are normal strings, but with the special attributes:
988 These are normal strings, but with the special attributes:
975
989
976 .l (or .list) : value as list (split on newlines).
990 .l (or .list) : value as list (split on newlines).
977 .n (or .nlstr): original value (the string itself).
991 .n (or .nlstr): original value (the string itself).
978 .s (or .spstr): value as whitespace-separated string.
992 .s (or .spstr): value as whitespace-separated string.
979 .p (or .paths): list of path objects
993 .p (or .paths): list of path objects
980
994
981 Any values which require transformations are computed only once and
995 Any values which require transformations are computed only once and
982 cached.
996 cached.
983
997
984 Such strings are very useful to efficiently interact with the shell, which
998 Such strings are very useful to efficiently interact with the shell, which
985 typically only understands whitespace-separated options for commands."""
999 typically only understands whitespace-separated options for commands."""
986
1000
987 def get_list(self):
1001 def get_list(self):
988 try:
1002 try:
989 return self.__list
1003 return self.__list
990 except AttributeError:
1004 except AttributeError:
991 self.__list = self.split('\n')
1005 self.__list = self.split('\n')
992 return self.__list
1006 return self.__list
993
1007
994 l = list = property(get_list)
1008 l = list = property(get_list)
995
1009
996 def get_spstr(self):
1010 def get_spstr(self):
997 try:
1011 try:
998 return self.__spstr
1012 return self.__spstr
999 except AttributeError:
1013 except AttributeError:
1000 self.__spstr = self.replace('\n',' ')
1014 self.__spstr = self.replace('\n',' ')
1001 return self.__spstr
1015 return self.__spstr
1002
1016
1003 s = spstr = property(get_spstr)
1017 s = spstr = property(get_spstr)
1004
1018
1005 def get_nlstr(self):
1019 def get_nlstr(self):
1006 return self
1020 return self
1007
1021
1008 n = nlstr = property(get_nlstr)
1022 n = nlstr = property(get_nlstr)
1009
1023
1010 def get_paths(self):
1024 def get_paths(self):
1011 try:
1025 try:
1012 return self.__paths
1026 return self.__paths
1013 except AttributeError:
1027 except AttributeError:
1014 self.__paths = [path(p) for p in self.split('\n') if os.path.exists(p)]
1028 self.__paths = [path(p) for p in self.split('\n') if os.path.exists(p)]
1015 return self.__paths
1029 return self.__paths
1016
1030
1017 p = paths = property(get_paths)
1031 p = paths = property(get_paths)
1018
1032
1019 def print_lsstring(arg):
1033 def print_lsstring(arg):
1020 """ Prettier (non-repr-like) and more informative printer for LSString """
1034 """ Prettier (non-repr-like) and more informative printer for LSString """
1021 print "LSString (.p, .n, .l, .s available). Value:"
1035 print "LSString (.p, .n, .l, .s available). Value:"
1022 print arg
1036 print arg
1023
1037
1024 print_lsstring = result_display.when_type(LSString)(print_lsstring)
1038 print_lsstring = result_display.when_type(LSString)(print_lsstring)
1025
1039
1026 #----------------------------------------------------------------------------
1040 #----------------------------------------------------------------------------
1027 class SList(list):
1041 class SList(list):
1028 """List derivative with a special access attributes.
1042 """List derivative with a special access attributes.
1029
1043
1030 These are normal lists, but with the special attributes:
1044 These are normal lists, but with the special attributes:
1031
1045
1032 .l (or .list) : value as list (the list itself).
1046 .l (or .list) : value as list (the list itself).
1033 .n (or .nlstr): value as a string, joined on newlines.
1047 .n (or .nlstr): value as a string, joined on newlines.
1034 .s (or .spstr): value as a string, joined on spaces.
1048 .s (or .spstr): value as a string, joined on spaces.
1035 .p (or .paths): list of path objects
1049 .p (or .paths): list of path objects
1036
1050
1037 Any values which require transformations are computed only once and
1051 Any values which require transformations are computed only once and
1038 cached."""
1052 cached."""
1039
1053
1040 def get_list(self):
1054 def get_list(self):
1041 return self
1055 return self
1042
1056
1043 l = list = property(get_list)
1057 l = list = property(get_list)
1044
1058
1045 def get_spstr(self):
1059 def get_spstr(self):
1046 try:
1060 try:
1047 return self.__spstr
1061 return self.__spstr
1048 except AttributeError:
1062 except AttributeError:
1049 self.__spstr = ' '.join(self)
1063 self.__spstr = ' '.join(self)
1050 return self.__spstr
1064 return self.__spstr
1051
1065
1052 s = spstr = property(get_spstr)
1066 s = spstr = property(get_spstr)
1053
1067
1054 def get_nlstr(self):
1068 def get_nlstr(self):
1055 try:
1069 try:
1056 return self.__nlstr
1070 return self.__nlstr
1057 except AttributeError:
1071 except AttributeError:
1058 self.__nlstr = '\n'.join(self)
1072 self.__nlstr = '\n'.join(self)
1059 return self.__nlstr
1073 return self.__nlstr
1060
1074
1061 n = nlstr = property(get_nlstr)
1075 n = nlstr = property(get_nlstr)
1062
1076
1063 def get_paths(self):
1077 def get_paths(self):
1064 try:
1078 try:
1065 return self.__paths
1079 return self.__paths
1066 except AttributeError:
1080 except AttributeError:
1067 self.__paths = [path(p) for p in self if os.path.exists(p)]
1081 self.__paths = [path(p) for p in self if os.path.exists(p)]
1068 return self.__paths
1082 return self.__paths
1069
1083
1070 p = paths = property(get_paths)
1084 p = paths = property(get_paths)
1071
1085
1072 def grep(self, pattern, prune = False, field = None):
1086 def grep(self, pattern, prune = False, field = None):
1073 """ Return all strings matching 'pattern' (a regex or callable)
1087 """ Return all strings matching 'pattern' (a regex or callable)
1074
1088
1075 This is case-insensitive. If prune is true, return all items
1089 This is case-insensitive. If prune is true, return all items
1076 NOT matching the pattern.
1090 NOT matching the pattern.
1077
1091
1078 If field is specified, the match must occur in the specified
1092 If field is specified, the match must occur in the specified
1079 whitespace-separated field.
1093 whitespace-separated field.
1080
1094
1081 Examples::
1095 Examples::
1082
1096
1083 a.grep( lambda x: x.startswith('C') )
1097 a.grep( lambda x: x.startswith('C') )
1084 a.grep('Cha.*log', prune=1)
1098 a.grep('Cha.*log', prune=1)
1085 a.grep('chm', field=-1)
1099 a.grep('chm', field=-1)
1086 """
1100 """
1087
1101
1088 def match_target(s):
1102 def match_target(s):
1089 if field is None:
1103 if field is None:
1090 return s
1104 return s
1091 parts = s.split()
1105 parts = s.split()
1092 try:
1106 try:
1093 tgt = parts[field]
1107 tgt = parts[field]
1094 return tgt
1108 return tgt
1095 except IndexError:
1109 except IndexError:
1096 return ""
1110 return ""
1097
1111
1098 if isinstance(pattern, basestring):
1112 if isinstance(pattern, basestring):
1099 pred = lambda x : re.search(pattern, x, re.IGNORECASE)
1113 pred = lambda x : re.search(pattern, x, re.IGNORECASE)
1100 else:
1114 else:
1101 pred = pattern
1115 pred = pattern
1102 if not prune:
1116 if not prune:
1103 return SList([el for el in self if pred(match_target(el))])
1117 return SList([el for el in self if pred(match_target(el))])
1104 else:
1118 else:
1105 return SList([el for el in self if not pred(match_target(el))])
1119 return SList([el for el in self if not pred(match_target(el))])
1106 def fields(self, *fields):
1120 def fields(self, *fields):
1107 """ Collect whitespace-separated fields from string list
1121 """ Collect whitespace-separated fields from string list
1108
1122
1109 Allows quick awk-like usage of string lists.
1123 Allows quick awk-like usage of string lists.
1110
1124
1111 Example data (in var a, created by 'a = !ls -l')::
1125 Example data (in var a, created by 'a = !ls -l')::
1112 -rwxrwxrwx 1 ville None 18 Dec 14 2006 ChangeLog
1126 -rwxrwxrwx 1 ville None 18 Dec 14 2006 ChangeLog
1113 drwxrwxrwx+ 6 ville None 0 Oct 24 18:05 IPython
1127 drwxrwxrwx+ 6 ville None 0 Oct 24 18:05 IPython
1114
1128
1115 a.fields(0) is ['-rwxrwxrwx', 'drwxrwxrwx+']
1129 a.fields(0) is ['-rwxrwxrwx', 'drwxrwxrwx+']
1116 a.fields(1,0) is ['1 -rwxrwxrwx', '6 drwxrwxrwx+']
1130 a.fields(1,0) is ['1 -rwxrwxrwx', '6 drwxrwxrwx+']
1117 (note the joining by space).
1131 (note the joining by space).
1118 a.fields(-1) is ['ChangeLog', 'IPython']
1132 a.fields(-1) is ['ChangeLog', 'IPython']
1119
1133
1120 IndexErrors are ignored.
1134 IndexErrors are ignored.
1121
1135
1122 Without args, fields() just split()'s the strings.
1136 Without args, fields() just split()'s the strings.
1123 """
1137 """
1124 if len(fields) == 0:
1138 if len(fields) == 0:
1125 return [el.split() for el in self]
1139 return [el.split() for el in self]
1126
1140
1127 res = SList()
1141 res = SList()
1128 for el in [f.split() for f in self]:
1142 for el in [f.split() for f in self]:
1129 lineparts = []
1143 lineparts = []
1130
1144
1131 for fd in fields:
1145 for fd in fields:
1132 try:
1146 try:
1133 lineparts.append(el[fd])
1147 lineparts.append(el[fd])
1134 except IndexError:
1148 except IndexError:
1135 pass
1149 pass
1136 if lineparts:
1150 if lineparts:
1137 res.append(" ".join(lineparts))
1151 res.append(" ".join(lineparts))
1138
1152
1139 return res
1153 return res
1140 def sort(self,field= None, nums = False):
1154 def sort(self,field= None, nums = False):
1141 """ sort by specified fields (see fields())
1155 """ sort by specified fields (see fields())
1142
1156
1143 Example::
1157 Example::
1144 a.sort(1, nums = True)
1158 a.sort(1, nums = True)
1145
1159
1146 Sorts a by second field, in numerical order (so that 21 > 3)
1160 Sorts a by second field, in numerical order (so that 21 > 3)
1147
1161
1148 """
1162 """
1149
1163
1150 #decorate, sort, undecorate
1164 #decorate, sort, undecorate
1151 if field is not None:
1165 if field is not None:
1152 dsu = [[SList([line]).fields(field), line] for line in self]
1166 dsu = [[SList([line]).fields(field), line] for line in self]
1153 else:
1167 else:
1154 dsu = [[line, line] for line in self]
1168 dsu = [[line, line] for line in self]
1155 if nums:
1169 if nums:
1156 for i in range(len(dsu)):
1170 for i in range(len(dsu)):
1157 numstr = "".join([ch for ch in dsu[i][0] if ch.isdigit()])
1171 numstr = "".join([ch for ch in dsu[i][0] if ch.isdigit()])
1158 try:
1172 try:
1159 n = int(numstr)
1173 n = int(numstr)
1160 except ValueError:
1174 except ValueError:
1161 n = 0;
1175 n = 0;
1162 dsu[i][0] = n
1176 dsu[i][0] = n
1163
1177
1164
1178
1165 dsu.sort()
1179 dsu.sort()
1166 return SList([t[1] for t in dsu])
1180 return SList([t[1] for t in dsu])
1167
1181
1168 def print_slist(arg):
1182 def print_slist(arg):
1169 """ Prettier (non-repr-like) and more informative printer for SList """
1183 """ Prettier (non-repr-like) and more informative printer for SList """
1170 print "SList (.p, .n, .l, .s, .grep(), .fields(), sort() available):"
1184 print "SList (.p, .n, .l, .s, .grep(), .fields(), sort() available):"
1171 if hasattr(arg, 'hideonce') and arg.hideonce:
1185 if hasattr(arg, 'hideonce') and arg.hideonce:
1172 arg.hideonce = False
1186 arg.hideonce = False
1173 return
1187 return
1174
1188
1175 nlprint(arg)
1189 nlprint(arg)
1176
1190
1177 print_slist = result_display.when_type(SList)(print_slist)
1191 print_slist = result_display.when_type(SList)(print_slist)
1178
1192
1179
1193
1180
1194
1181 #----------------------------------------------------------------------------
1195 #----------------------------------------------------------------------------
1182 def esc_quotes(strng):
1196 def esc_quotes(strng):
1183 """Return the input string with single and double quotes escaped out"""
1197 """Return the input string with single and double quotes escaped out"""
1184
1198
1185 return strng.replace('"','\\"').replace("'","\\'")
1199 return strng.replace('"','\\"').replace("'","\\'")
1186
1200
1187 #----------------------------------------------------------------------------
1201 #----------------------------------------------------------------------------
1188 def make_quoted_expr(s):
1202 def make_quoted_expr(s):
1189 """Return string s in appropriate quotes, using raw string if possible.
1203 """Return string s in appropriate quotes, using raw string if possible.
1190
1204
1191 Effectively this turns string: cd \ao\ao\
1205 Effectively this turns string: cd \ao\ao\
1192 to: r"cd \ao\ao\_"[:-1]
1206 to: r"cd \ao\ao\_"[:-1]
1193
1207
1194 Note the use of raw string and padding at the end to allow trailing backslash.
1208 Note the use of raw string and padding at the end to allow trailing backslash.
1195
1209
1196 """
1210 """
1197
1211
1198 tail = ''
1212 tail = ''
1199 tailpadding = ''
1213 tailpadding = ''
1200 raw = ''
1214 raw = ''
1201 if "\\" in s:
1215 if "\\" in s:
1202 raw = 'r'
1216 raw = 'r'
1203 if s.endswith('\\'):
1217 if s.endswith('\\'):
1204 tail = '[:-1]'
1218 tail = '[:-1]'
1205 tailpadding = '_'
1219 tailpadding = '_'
1206 if '"' not in s:
1220 if '"' not in s:
1207 quote = '"'
1221 quote = '"'
1208 elif "'" not in s:
1222 elif "'" not in s:
1209 quote = "'"
1223 quote = "'"
1210 elif '"""' not in s and not s.endswith('"'):
1224 elif '"""' not in s and not s.endswith('"'):
1211 quote = '"""'
1225 quote = '"""'
1212 elif "'''" not in s and not s.endswith("'"):
1226 elif "'''" not in s and not s.endswith("'"):
1213 quote = "'''"
1227 quote = "'''"
1214 else:
1228 else:
1215 # give up, backslash-escaped string will do
1229 # give up, backslash-escaped string will do
1216 return '"%s"' % esc_quotes(s)
1230 return '"%s"' % esc_quotes(s)
1217 res = raw + quote + s + tailpadding + quote + tail
1231 res = raw + quote + s + tailpadding + quote + tail
1218 return res
1232 return res
1219
1233
1220
1234
1221 #----------------------------------------------------------------------------
1235 #----------------------------------------------------------------------------
1222 def raw_input_multi(header='', ps1='==> ', ps2='..> ',terminate_str = '.'):
1236 def raw_input_multi(header='', ps1='==> ', ps2='..> ',terminate_str = '.'):
1223 """Take multiple lines of input.
1237 """Take multiple lines of input.
1224
1238
1225 A list with each line of input as a separate element is returned when a
1239 A list with each line of input as a separate element is returned when a
1226 termination string is entered (defaults to a single '.'). Input can also
1240 termination string is entered (defaults to a single '.'). Input can also
1227 terminate via EOF (^D in Unix, ^Z-RET in Windows).
1241 terminate via EOF (^D in Unix, ^Z-RET in Windows).
1228
1242
1229 Lines of input which end in \\ are joined into single entries (and a
1243 Lines of input which end in \\ are joined into single entries (and a
1230 secondary continuation prompt is issued as long as the user terminates
1244 secondary continuation prompt is issued as long as the user terminates
1231 lines with \\). This allows entering very long strings which are still
1245 lines with \\). This allows entering very long strings which are still
1232 meant to be treated as single entities.
1246 meant to be treated as single entities.
1233 """
1247 """
1234
1248
1235 try:
1249 try:
1236 if header:
1250 if header:
1237 header += '\n'
1251 header += '\n'
1238 lines = [raw_input(header + ps1)]
1252 lines = [raw_input(header + ps1)]
1239 except EOFError:
1253 except EOFError:
1240 return []
1254 return []
1241 terminate = [terminate_str]
1255 terminate = [terminate_str]
1242 try:
1256 try:
1243 while lines[-1:] != terminate:
1257 while lines[-1:] != terminate:
1244 new_line = raw_input(ps1)
1258 new_line = raw_input(ps1)
1245 while new_line.endswith('\\'):
1259 while new_line.endswith('\\'):
1246 new_line = new_line[:-1] + raw_input(ps2)
1260 new_line = new_line[:-1] + raw_input(ps2)
1247 lines.append(new_line)
1261 lines.append(new_line)
1248
1262
1249 return lines[:-1] # don't return the termination command
1263 return lines[:-1] # don't return the termination command
1250 except EOFError:
1264 except EOFError:
1251 print
1265 print
1252 return lines
1266 return lines
1253
1267
1254 #----------------------------------------------------------------------------
1268 #----------------------------------------------------------------------------
1255 def raw_input_ext(prompt='', ps2='... '):
1269 def raw_input_ext(prompt='', ps2='... '):
1256 """Similar to raw_input(), but accepts extended lines if input ends with \\."""
1270 """Similar to raw_input(), but accepts extended lines if input ends with \\."""
1257
1271
1258 line = raw_input(prompt)
1272 line = raw_input(prompt)
1259 while line.endswith('\\'):
1273 while line.endswith('\\'):
1260 line = line[:-1] + raw_input(ps2)
1274 line = line[:-1] + raw_input(ps2)
1261 return line
1275 return line
1262
1276
1263 #----------------------------------------------------------------------------
1277 #----------------------------------------------------------------------------
1264 def ask_yes_no(prompt,default=None):
1278 def ask_yes_no(prompt,default=None):
1265 """Asks a question and returns a boolean (y/n) answer.
1279 """Asks a question and returns a boolean (y/n) answer.
1266
1280
1267 If default is given (one of 'y','n'), it is used if the user input is
1281 If default is given (one of 'y','n'), it is used if the user input is
1268 empty. Otherwise the question is repeated until an answer is given.
1282 empty. Otherwise the question is repeated until an answer is given.
1269
1283
1270 An EOF is treated as the default answer. If there is no default, an
1284 An EOF is treated as the default answer. If there is no default, an
1271 exception is raised to prevent infinite loops.
1285 exception is raised to prevent infinite loops.
1272
1286
1273 Valid answers are: y/yes/n/no (match is not case sensitive)."""
1287 Valid answers are: y/yes/n/no (match is not case sensitive)."""
1274
1288
1275 answers = {'y':True,'n':False,'yes':True,'no':False}
1289 answers = {'y':True,'n':False,'yes':True,'no':False}
1276 ans = None
1290 ans = None
1277 while ans not in answers.keys():
1291 while ans not in answers.keys():
1278 try:
1292 try:
1279 ans = raw_input(prompt+' ').lower()
1293 ans = raw_input(prompt+' ').lower()
1280 if not ans: # response was an empty string
1294 if not ans: # response was an empty string
1281 ans = default
1295 ans = default
1282 except KeyboardInterrupt:
1296 except KeyboardInterrupt:
1283 pass
1297 pass
1284 except EOFError:
1298 except EOFError:
1285 if default in answers.keys():
1299 if default in answers.keys():
1286 ans = default
1300 ans = default
1287 print
1301 print
1288 else:
1302 else:
1289 raise
1303 raise
1290
1304
1291 return answers[ans]
1305 return answers[ans]
1292
1306
1293 #----------------------------------------------------------------------------
1307 #----------------------------------------------------------------------------
1294 def marquee(txt='',width=78,mark='*'):
1308 def marquee(txt='',width=78,mark='*'):
1295 """Return the input string centered in a 'marquee'."""
1309 """Return the input string centered in a 'marquee'."""
1296 if not txt:
1310 if not txt:
1297 return (mark*width)[:width]
1311 return (mark*width)[:width]
1298 nmark = (width-len(txt)-2)/len(mark)/2
1312 nmark = (width-len(txt)-2)/len(mark)/2
1299 if nmark < 0: nmark =0
1313 if nmark < 0: nmark =0
1300 marks = mark*nmark
1314 marks = mark*nmark
1301 return '%s %s %s' % (marks,txt,marks)
1315 return '%s %s %s' % (marks,txt,marks)
1302
1316
1303 #----------------------------------------------------------------------------
1317 #----------------------------------------------------------------------------
1304 class EvalDict:
1318 class EvalDict:
1305 """
1319 """
1306 Emulate a dict which evaluates its contents in the caller's frame.
1320 Emulate a dict which evaluates its contents in the caller's frame.
1307
1321
1308 Usage:
1322 Usage:
1309 >>> number = 19
1323 >>> number = 19
1310
1324
1311 >>> text = "python"
1325 >>> text = "python"
1312
1326
1313 >>> print "%(text.capitalize())s %(number/9.0).1f rules!" % EvalDict()
1327 >>> print "%(text.capitalize())s %(number/9.0).1f rules!" % EvalDict()
1314 Python 2.1 rules!
1328 Python 2.1 rules!
1315 """
1329 """
1316
1330
1317 # This version is due to sismex01@hebmex.com on c.l.py, and is basically a
1331 # This version is due to sismex01@hebmex.com on c.l.py, and is basically a
1318 # modified (shorter) version of:
1332 # modified (shorter) version of:
1319 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66018 by
1333 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66018 by
1320 # Skip Montanaro (skip@pobox.com).
1334 # Skip Montanaro (skip@pobox.com).
1321
1335
1322 def __getitem__(self, name):
1336 def __getitem__(self, name):
1323 frame = sys._getframe(1)
1337 frame = sys._getframe(1)
1324 return eval(name, frame.f_globals, frame.f_locals)
1338 return eval(name, frame.f_globals, frame.f_locals)
1325
1339
1326 EvalString = EvalDict # for backwards compatibility
1340 EvalString = EvalDict # for backwards compatibility
1327 #----------------------------------------------------------------------------
1341 #----------------------------------------------------------------------------
1328 def qw(words,flat=0,sep=None,maxsplit=-1):
1342 def qw(words,flat=0,sep=None,maxsplit=-1):
1329 """Similar to Perl's qw() operator, but with some more options.
1343 """Similar to Perl's qw() operator, but with some more options.
1330
1344
1331 qw(words,flat=0,sep=' ',maxsplit=-1) -> words.split(sep,maxsplit)
1345 qw(words,flat=0,sep=' ',maxsplit=-1) -> words.split(sep,maxsplit)
1332
1346
1333 words can also be a list itself, and with flat=1, the output will be
1347 words can also be a list itself, and with flat=1, the output will be
1334 recursively flattened.
1348 recursively flattened.
1335
1349
1336 Examples:
1350 Examples:
1337
1351
1338 >>> qw('1 2')
1352 >>> qw('1 2')
1339 ['1', '2']
1353 ['1', '2']
1340
1354
1341 >>> qw(['a b','1 2',['m n','p q']])
1355 >>> qw(['a b','1 2',['m n','p q']])
1342 [['a', 'b'], ['1', '2'], [['m', 'n'], ['p', 'q']]]
1356 [['a', 'b'], ['1', '2'], [['m', 'n'], ['p', 'q']]]
1343
1357
1344 >>> qw(['a b','1 2',['m n','p q']],flat=1)
1358 >>> qw(['a b','1 2',['m n','p q']],flat=1)
1345 ['a', 'b', '1', '2', 'm', 'n', 'p', 'q']
1359 ['a', 'b', '1', '2', 'm', 'n', 'p', 'q']
1346 """
1360 """
1347
1361
1348 if type(words) in StringTypes:
1362 if type(words) in StringTypes:
1349 return [word.strip() for word in words.split(sep,maxsplit)
1363 return [word.strip() for word in words.split(sep,maxsplit)
1350 if word and not word.isspace() ]
1364 if word and not word.isspace() ]
1351 if flat:
1365 if flat:
1352 return flatten(map(qw,words,[1]*len(words)))
1366 return flatten(map(qw,words,[1]*len(words)))
1353 return map(qw,words)
1367 return map(qw,words)
1354
1368
1355 #----------------------------------------------------------------------------
1369 #----------------------------------------------------------------------------
1356 def qwflat(words,sep=None,maxsplit=-1):
1370 def qwflat(words,sep=None,maxsplit=-1):
1357 """Calls qw(words) in flat mode. It's just a convenient shorthand."""
1371 """Calls qw(words) in flat mode. It's just a convenient shorthand."""
1358 return qw(words,1,sep,maxsplit)
1372 return qw(words,1,sep,maxsplit)
1359
1373
1360 #----------------------------------------------------------------------------
1374 #----------------------------------------------------------------------------
1361 def qw_lol(indata):
1375 def qw_lol(indata):
1362 """qw_lol('a b') -> [['a','b']],
1376 """qw_lol('a b') -> [['a','b']],
1363 otherwise it's just a call to qw().
1377 otherwise it's just a call to qw().
1364
1378
1365 We need this to make sure the modules_some keys *always* end up as a
1379 We need this to make sure the modules_some keys *always* end up as a
1366 list of lists."""
1380 list of lists."""
1367
1381
1368 if type(indata) in StringTypes:
1382 if type(indata) in StringTypes:
1369 return [qw(indata)]
1383 return [qw(indata)]
1370 else:
1384 else:
1371 return qw(indata)
1385 return qw(indata)
1372
1386
1373 #-----------------------------------------------------------------------------
1387 #-----------------------------------------------------------------------------
1374 def list_strings(arg):
1388 def list_strings(arg):
1375 """Always return a list of strings, given a string or list of strings
1389 """Always return a list of strings, given a string or list of strings
1376 as input."""
1390 as input."""
1377
1391
1378 if type(arg) in StringTypes: return [arg]
1392 if type(arg) in StringTypes: return [arg]
1379 else: return arg
1393 else: return arg
1380
1394
1381 #----------------------------------------------------------------------------
1395 #----------------------------------------------------------------------------
1382 def grep(pat,list,case=1):
1396 def grep(pat,list,case=1):
1383 """Simple minded grep-like function.
1397 """Simple minded grep-like function.
1384 grep(pat,list) returns occurrences of pat in list, None on failure.
1398 grep(pat,list) returns occurrences of pat in list, None on failure.
1385
1399
1386 It only does simple string matching, with no support for regexps. Use the
1400 It only does simple string matching, with no support for regexps. Use the
1387 option case=0 for case-insensitive matching."""
1401 option case=0 for case-insensitive matching."""
1388
1402
1389 # This is pretty crude. At least it should implement copying only references
1403 # This is pretty crude. At least it should implement copying only references
1390 # to the original data in case it's big. Now it copies the data for output.
1404 # to the original data in case it's big. Now it copies the data for output.
1391 out=[]
1405 out=[]
1392 if case:
1406 if case:
1393 for term in list:
1407 for term in list:
1394 if term.find(pat)>-1: out.append(term)
1408 if term.find(pat)>-1: out.append(term)
1395 else:
1409 else:
1396 lpat=pat.lower()
1410 lpat=pat.lower()
1397 for term in list:
1411 for term in list:
1398 if term.lower().find(lpat)>-1: out.append(term)
1412 if term.lower().find(lpat)>-1: out.append(term)
1399
1413
1400 if len(out): return out
1414 if len(out): return out
1401 else: return None
1415 else: return None
1402
1416
1403 #----------------------------------------------------------------------------
1417 #----------------------------------------------------------------------------
1404 def dgrep(pat,*opts):
1418 def dgrep(pat,*opts):
1405 """Return grep() on dir()+dir(__builtins__).
1419 """Return grep() on dir()+dir(__builtins__).
1406
1420
1407 A very common use of grep() when working interactively."""
1421 A very common use of grep() when working interactively."""
1408
1422
1409 return grep(pat,dir(__main__)+dir(__main__.__builtins__),*opts)
1423 return grep(pat,dir(__main__)+dir(__main__.__builtins__),*opts)
1410
1424
1411 #----------------------------------------------------------------------------
1425 #----------------------------------------------------------------------------
1412 def idgrep(pat):
1426 def idgrep(pat):
1413 """Case-insensitive dgrep()"""
1427 """Case-insensitive dgrep()"""
1414
1428
1415 return dgrep(pat,0)
1429 return dgrep(pat,0)
1416
1430
1417 #----------------------------------------------------------------------------
1431 #----------------------------------------------------------------------------
1418 def igrep(pat,list):
1432 def igrep(pat,list):
1419 """Synonym for case-insensitive grep."""
1433 """Synonym for case-insensitive grep."""
1420
1434
1421 return grep(pat,list,case=0)
1435 return grep(pat,list,case=0)
1422
1436
1423 #----------------------------------------------------------------------------
1437 #----------------------------------------------------------------------------
1424 def indent(str,nspaces=4,ntabs=0):
1438 def indent(str,nspaces=4,ntabs=0):
1425 """Indent a string a given number of spaces or tabstops.
1439 """Indent a string a given number of spaces or tabstops.
1426
1440
1427 indent(str,nspaces=4,ntabs=0) -> indent str by ntabs+nspaces.
1441 indent(str,nspaces=4,ntabs=0) -> indent str by ntabs+nspaces.
1428 """
1442 """
1429 if str is None:
1443 if str is None:
1430 return
1444 return
1431 ind = '\t'*ntabs+' '*nspaces
1445 ind = '\t'*ntabs+' '*nspaces
1432 outstr = '%s%s' % (ind,str.replace(os.linesep,os.linesep+ind))
1446 outstr = '%s%s' % (ind,str.replace(os.linesep,os.linesep+ind))
1433 if outstr.endswith(os.linesep+ind):
1447 if outstr.endswith(os.linesep+ind):
1434 return outstr[:-len(ind)]
1448 return outstr[:-len(ind)]
1435 else:
1449 else:
1436 return outstr
1450 return outstr
1437
1451
1438 #-----------------------------------------------------------------------------
1452 #-----------------------------------------------------------------------------
1439 def native_line_ends(filename,backup=1):
1453 def native_line_ends(filename,backup=1):
1440 """Convert (in-place) a file to line-ends native to the current OS.
1454 """Convert (in-place) a file to line-ends native to the current OS.
1441
1455
1442 If the optional backup argument is given as false, no backup of the
1456 If the optional backup argument is given as false, no backup of the
1443 original file is left. """
1457 original file is left. """
1444
1458
1445 backup_suffixes = {'posix':'~','dos':'.bak','nt':'.bak','mac':'.bak'}
1459 backup_suffixes = {'posix':'~','dos':'.bak','nt':'.bak','mac':'.bak'}
1446
1460
1447 bak_filename = filename + backup_suffixes[os.name]
1461 bak_filename = filename + backup_suffixes[os.name]
1448
1462
1449 original = open(filename).read()
1463 original = open(filename).read()
1450 shutil.copy2(filename,bak_filename)
1464 shutil.copy2(filename,bak_filename)
1451 try:
1465 try:
1452 new = open(filename,'wb')
1466 new = open(filename,'wb')
1453 new.write(os.linesep.join(original.splitlines()))
1467 new.write(os.linesep.join(original.splitlines()))
1454 new.write(os.linesep) # ALWAYS put an eol at the end of the file
1468 new.write(os.linesep) # ALWAYS put an eol at the end of the file
1455 new.close()
1469 new.close()
1456 except:
1470 except:
1457 os.rename(bak_filename,filename)
1471 os.rename(bak_filename,filename)
1458 if not backup:
1472 if not backup:
1459 try:
1473 try:
1460 os.remove(bak_filename)
1474 os.remove(bak_filename)
1461 except:
1475 except:
1462 pass
1476 pass
1463
1477
1464 #----------------------------------------------------------------------------
1478 #----------------------------------------------------------------------------
1465 def get_pager_cmd(pager_cmd = None):
1479 def get_pager_cmd(pager_cmd = None):
1466 """Return a pager command.
1480 """Return a pager command.
1467
1481
1468 Makes some attempts at finding an OS-correct one."""
1482 Makes some attempts at finding an OS-correct one."""
1469
1483
1470 if os.name == 'posix':
1484 if os.name == 'posix':
1471 default_pager_cmd = 'less -r' # -r for color control sequences
1485 default_pager_cmd = 'less -r' # -r for color control sequences
1472 elif os.name in ['nt','dos']:
1486 elif os.name in ['nt','dos']:
1473 default_pager_cmd = 'type'
1487 default_pager_cmd = 'type'
1474
1488
1475 if pager_cmd is None:
1489 if pager_cmd is None:
1476 try:
1490 try:
1477 pager_cmd = os.environ['PAGER']
1491 pager_cmd = os.environ['PAGER']
1478 except:
1492 except:
1479 pager_cmd = default_pager_cmd
1493 pager_cmd = default_pager_cmd
1480 return pager_cmd
1494 return pager_cmd
1481
1495
1482 #-----------------------------------------------------------------------------
1496 #-----------------------------------------------------------------------------
1483 def get_pager_start(pager,start):
1497 def get_pager_start(pager,start):
1484 """Return the string for paging files with an offset.
1498 """Return the string for paging files with an offset.
1485
1499
1486 This is the '+N' argument which less and more (under Unix) accept.
1500 This is the '+N' argument which less and more (under Unix) accept.
1487 """
1501 """
1488
1502
1489 if pager in ['less','more']:
1503 if pager in ['less','more']:
1490 if start:
1504 if start:
1491 start_string = '+' + str(start)
1505 start_string = '+' + str(start)
1492 else:
1506 else:
1493 start_string = ''
1507 start_string = ''
1494 else:
1508 else:
1495 start_string = ''
1509 start_string = ''
1496 return start_string
1510 return start_string
1497
1511
1498 #----------------------------------------------------------------------------
1512 #----------------------------------------------------------------------------
1499 # (X)emacs on W32 doesn't like to be bypassed with msvcrt.getch()
1513 # (X)emacs on W32 doesn't like to be bypassed with msvcrt.getch()
1500 if os.name == 'nt' and os.environ.get('TERM','dumb') != 'emacs':
1514 if os.name == 'nt' and os.environ.get('TERM','dumb') != 'emacs':
1501 import msvcrt
1515 import msvcrt
1502 def page_more():
1516 def page_more():
1503 """ Smart pausing between pages
1517 """ Smart pausing between pages
1504
1518
1505 @return: True if need print more lines, False if quit
1519 @return: True if need print more lines, False if quit
1506 """
1520 """
1507 Term.cout.write('---Return to continue, q to quit--- ')
1521 Term.cout.write('---Return to continue, q to quit--- ')
1508 ans = msvcrt.getch()
1522 ans = msvcrt.getch()
1509 if ans in ("q", "Q"):
1523 if ans in ("q", "Q"):
1510 result = False
1524 result = False
1511 else:
1525 else:
1512 result = True
1526 result = True
1513 Term.cout.write("\b"*37 + " "*37 + "\b"*37)
1527 Term.cout.write("\b"*37 + " "*37 + "\b"*37)
1514 return result
1528 return result
1515 else:
1529 else:
1516 def page_more():
1530 def page_more():
1517 ans = raw_input('---Return to continue, q to quit--- ')
1531 ans = raw_input('---Return to continue, q to quit--- ')
1518 if ans.lower().startswith('q'):
1532 if ans.lower().startswith('q'):
1519 return False
1533 return False
1520 else:
1534 else:
1521 return True
1535 return True
1522
1536
1523 esc_re = re.compile(r"(\x1b[^m]+m)")
1537 esc_re = re.compile(r"(\x1b[^m]+m)")
1524
1538
1525 def page_dumb(strng,start=0,screen_lines=25):
1539 def page_dumb(strng,start=0,screen_lines=25):
1526 """Very dumb 'pager' in Python, for when nothing else works.
1540 """Very dumb 'pager' in Python, for when nothing else works.
1527
1541
1528 Only moves forward, same interface as page(), except for pager_cmd and
1542 Only moves forward, same interface as page(), except for pager_cmd and
1529 mode."""
1543 mode."""
1530
1544
1531 out_ln = strng.splitlines()[start:]
1545 out_ln = strng.splitlines()[start:]
1532 screens = chop(out_ln,screen_lines-1)
1546 screens = chop(out_ln,screen_lines-1)
1533 if len(screens) == 1:
1547 if len(screens) == 1:
1534 print >>Term.cout, os.linesep.join(screens[0])
1548 print >>Term.cout, os.linesep.join(screens[0])
1535 else:
1549 else:
1536 last_escape = ""
1550 last_escape = ""
1537 for scr in screens[0:-1]:
1551 for scr in screens[0:-1]:
1538 hunk = os.linesep.join(scr)
1552 hunk = os.linesep.join(scr)
1539 print >>Term.cout, last_escape + hunk
1553 print >>Term.cout, last_escape + hunk
1540 if not page_more():
1554 if not page_more():
1541 return
1555 return
1542 esc_list = esc_re.findall(hunk)
1556 esc_list = esc_re.findall(hunk)
1543 if len(esc_list) > 0:
1557 if len(esc_list) > 0:
1544 last_escape = esc_list[-1]
1558 last_escape = esc_list[-1]
1545 print >>Term.cout, last_escape + os.linesep.join(screens[-1])
1559 print >>Term.cout, last_escape + os.linesep.join(screens[-1])
1546
1560
1547 #----------------------------------------------------------------------------
1561 #----------------------------------------------------------------------------
1548 def page(strng,start=0,screen_lines=0,pager_cmd = None):
1562 def page(strng,start=0,screen_lines=0,pager_cmd = None):
1549 """Print a string, piping through a pager after a certain length.
1563 """Print a string, piping through a pager after a certain length.
1550
1564
1551 The screen_lines parameter specifies the number of *usable* lines of your
1565 The screen_lines parameter specifies the number of *usable* lines of your
1552 terminal screen (total lines minus lines you need to reserve to show other
1566 terminal screen (total lines minus lines you need to reserve to show other
1553 information).
1567 information).
1554
1568
1555 If you set screen_lines to a number <=0, page() will try to auto-determine
1569 If you set screen_lines to a number <=0, page() will try to auto-determine
1556 your screen size and will only use up to (screen_size+screen_lines) for
1570 your screen size and will only use up to (screen_size+screen_lines) for
1557 printing, paging after that. That is, if you want auto-detection but need
1571 printing, paging after that. That is, if you want auto-detection but need
1558 to reserve the bottom 3 lines of the screen, use screen_lines = -3, and for
1572 to reserve the bottom 3 lines of the screen, use screen_lines = -3, and for
1559 auto-detection without any lines reserved simply use screen_lines = 0.
1573 auto-detection without any lines reserved simply use screen_lines = 0.
1560
1574
1561 If a string won't fit in the allowed lines, it is sent through the
1575 If a string won't fit in the allowed lines, it is sent through the
1562 specified pager command. If none given, look for PAGER in the environment,
1576 specified pager command. If none given, look for PAGER in the environment,
1563 and ultimately default to less.
1577 and ultimately default to less.
1564
1578
1565 If no system pager works, the string is sent through a 'dumb pager'
1579 If no system pager works, the string is sent through a 'dumb pager'
1566 written in python, very simplistic.
1580 written in python, very simplistic.
1567 """
1581 """
1568
1582
1569 # Some routines may auto-compute start offsets incorrectly and pass a
1583 # Some routines may auto-compute start offsets incorrectly and pass a
1570 # negative value. Offset to 0 for robustness.
1584 # negative value. Offset to 0 for robustness.
1571 start = max(0,start)
1585 start = max(0,start)
1572
1586
1573 # first, try the hook
1587 # first, try the hook
1574 ip = IPython.ipapi.get()
1588 ip = IPython.ipapi.get()
1575 if ip:
1589 if ip:
1576 try:
1590 try:
1577 ip.IP.hooks.show_in_pager(strng)
1591 ip.IP.hooks.show_in_pager(strng)
1578 return
1592 return
1579 except IPython.ipapi.TryNext:
1593 except IPython.ipapi.TryNext:
1580 pass
1594 pass
1581
1595
1582 # Ugly kludge, but calling curses.initscr() flat out crashes in emacs
1596 # Ugly kludge, but calling curses.initscr() flat out crashes in emacs
1583 TERM = os.environ.get('TERM','dumb')
1597 TERM = os.environ.get('TERM','dumb')
1584 if TERM in ['dumb','emacs'] and os.name != 'nt':
1598 if TERM in ['dumb','emacs'] and os.name != 'nt':
1585 print strng
1599 print strng
1586 return
1600 return
1587 # chop off the topmost part of the string we don't want to see
1601 # chop off the topmost part of the string we don't want to see
1588 str_lines = strng.split(os.linesep)[start:]
1602 str_lines = strng.split(os.linesep)[start:]
1589 str_toprint = os.linesep.join(str_lines)
1603 str_toprint = os.linesep.join(str_lines)
1590 num_newlines = len(str_lines)
1604 num_newlines = len(str_lines)
1591 len_str = len(str_toprint)
1605 len_str = len(str_toprint)
1592
1606
1593 # Dumb heuristics to guesstimate number of on-screen lines the string
1607 # Dumb heuristics to guesstimate number of on-screen lines the string
1594 # takes. Very basic, but good enough for docstrings in reasonable
1608 # takes. Very basic, but good enough for docstrings in reasonable
1595 # terminals. If someone later feels like refining it, it's not hard.
1609 # terminals. If someone later feels like refining it, it's not hard.
1596 numlines = max(num_newlines,int(len_str/80)+1)
1610 numlines = max(num_newlines,int(len_str/80)+1)
1597
1611
1598 if os.name == "nt":
1612 if os.name == "nt":
1599 screen_lines_def = get_console_size(defaulty=25)[1]
1613 screen_lines_def = get_console_size(defaulty=25)[1]
1600 else:
1614 else:
1601 screen_lines_def = 25 # default value if we can't auto-determine
1615 screen_lines_def = 25 # default value if we can't auto-determine
1602
1616
1603 # auto-determine screen size
1617 # auto-determine screen size
1604 if screen_lines <= 0:
1618 if screen_lines <= 0:
1605 if TERM=='xterm':
1619 if TERM=='xterm':
1606 use_curses = USE_CURSES
1620 use_curses = USE_CURSES
1607 else:
1621 else:
1608 # curses causes problems on many terminals other than xterm.
1622 # curses causes problems on many terminals other than xterm.
1609 use_curses = False
1623 use_curses = False
1610 if use_curses:
1624 if use_curses:
1611 # There is a bug in curses, where *sometimes* it fails to properly
1625 # There is a bug in curses, where *sometimes* it fails to properly
1612 # initialize, and then after the endwin() call is made, the
1626 # initialize, and then after the endwin() call is made, the
1613 # terminal is left in an unusable state. Rather than trying to
1627 # terminal is left in an unusable state. Rather than trying to
1614 # check everytime for this (by requesting and comparing termios
1628 # check everytime for this (by requesting and comparing termios
1615 # flags each time), we just save the initial terminal state and
1629 # flags each time), we just save the initial terminal state and
1616 # unconditionally reset it every time. It's cheaper than making
1630 # unconditionally reset it every time. It's cheaper than making
1617 # the checks.
1631 # the checks.
1618 term_flags = termios.tcgetattr(sys.stdout)
1632 term_flags = termios.tcgetattr(sys.stdout)
1619 scr = curses.initscr()
1633 scr = curses.initscr()
1620 screen_lines_real,screen_cols = scr.getmaxyx()
1634 screen_lines_real,screen_cols = scr.getmaxyx()
1621 curses.endwin()
1635 curses.endwin()
1622 # Restore terminal state in case endwin() didn't.
1636 # Restore terminal state in case endwin() didn't.
1623 termios.tcsetattr(sys.stdout,termios.TCSANOW,term_flags)
1637 termios.tcsetattr(sys.stdout,termios.TCSANOW,term_flags)
1624 # Now we have what we needed: the screen size in rows/columns
1638 # Now we have what we needed: the screen size in rows/columns
1625 screen_lines += screen_lines_real
1639 screen_lines += screen_lines_real
1626 #print '***Screen size:',screen_lines_real,'lines x',\
1640 #print '***Screen size:',screen_lines_real,'lines x',\
1627 #screen_cols,'columns.' # dbg
1641 #screen_cols,'columns.' # dbg
1628 else:
1642 else:
1629 screen_lines += screen_lines_def
1643 screen_lines += screen_lines_def
1630
1644
1631 #print 'numlines',numlines,'screenlines',screen_lines # dbg
1645 #print 'numlines',numlines,'screenlines',screen_lines # dbg
1632 if numlines <= screen_lines :
1646 if numlines <= screen_lines :
1633 #print '*** normal print' # dbg
1647 #print '*** normal print' # dbg
1634 print >>Term.cout, str_toprint
1648 print >>Term.cout, str_toprint
1635 else:
1649 else:
1636 # Try to open pager and default to internal one if that fails.
1650 # Try to open pager and default to internal one if that fails.
1637 # All failure modes are tagged as 'retval=1', to match the return
1651 # All failure modes are tagged as 'retval=1', to match the return
1638 # value of a failed system command. If any intermediate attempt
1652 # value of a failed system command. If any intermediate attempt
1639 # sets retval to 1, at the end we resort to our own page_dumb() pager.
1653 # sets retval to 1, at the end we resort to our own page_dumb() pager.
1640 pager_cmd = get_pager_cmd(pager_cmd)
1654 pager_cmd = get_pager_cmd(pager_cmd)
1641 pager_cmd += ' ' + get_pager_start(pager_cmd,start)
1655 pager_cmd += ' ' + get_pager_start(pager_cmd,start)
1642 if os.name == 'nt':
1656 if os.name == 'nt':
1643 if pager_cmd.startswith('type'):
1657 if pager_cmd.startswith('type'):
1644 # The default WinXP 'type' command is failing on complex strings.
1658 # The default WinXP 'type' command is failing on complex strings.
1645 retval = 1
1659 retval = 1
1646 else:
1660 else:
1647 tmpname = tempfile.mktemp('.txt')
1661 tmpname = tempfile.mktemp('.txt')
1648 tmpfile = file(tmpname,'wt')
1662 tmpfile = file(tmpname,'wt')
1649 tmpfile.write(strng)
1663 tmpfile.write(strng)
1650 tmpfile.close()
1664 tmpfile.close()
1651 cmd = "%s < %s" % (pager_cmd,tmpname)
1665 cmd = "%s < %s" % (pager_cmd,tmpname)
1652 if os.system(cmd):
1666 if os.system(cmd):
1653 retval = 1
1667 retval = 1
1654 else:
1668 else:
1655 retval = None
1669 retval = None
1656 os.remove(tmpname)
1670 os.remove(tmpname)
1657 else:
1671 else:
1658 try:
1672 try:
1659 retval = None
1673 retval = None
1660 # if I use popen4, things hang. No idea why.
1674 # if I use popen4, things hang. No idea why.
1661 #pager,shell_out = os.popen4(pager_cmd)
1675 #pager,shell_out = os.popen4(pager_cmd)
1662 pager = os.popen(pager_cmd,'w')
1676 pager = os.popen(pager_cmd,'w')
1663 pager.write(strng)
1677 pager.write(strng)
1664 pager.close()
1678 pager.close()
1665 retval = pager.close() # success returns None
1679 retval = pager.close() # success returns None
1666 except IOError,msg: # broken pipe when user quits
1680 except IOError,msg: # broken pipe when user quits
1667 if msg.args == (32,'Broken pipe'):
1681 if msg.args == (32,'Broken pipe'):
1668 retval = None
1682 retval = None
1669 else:
1683 else:
1670 retval = 1
1684 retval = 1
1671 except OSError:
1685 except OSError:
1672 # Other strange problems, sometimes seen in Win2k/cygwin
1686 # Other strange problems, sometimes seen in Win2k/cygwin
1673 retval = 1
1687 retval = 1
1674 if retval is not None:
1688 if retval is not None:
1675 page_dumb(strng,screen_lines=screen_lines)
1689 page_dumb(strng,screen_lines=screen_lines)
1676
1690
1677 #----------------------------------------------------------------------------
1691 #----------------------------------------------------------------------------
1678 def page_file(fname,start = 0, pager_cmd = None):
1692 def page_file(fname,start = 0, pager_cmd = None):
1679 """Page a file, using an optional pager command and starting line.
1693 """Page a file, using an optional pager command and starting line.
1680 """
1694 """
1681
1695
1682 pager_cmd = get_pager_cmd(pager_cmd)
1696 pager_cmd = get_pager_cmd(pager_cmd)
1683 pager_cmd += ' ' + get_pager_start(pager_cmd,start)
1697 pager_cmd += ' ' + get_pager_start(pager_cmd,start)
1684
1698
1685 try:
1699 try:
1686 if os.environ['TERM'] in ['emacs','dumb']:
1700 if os.environ['TERM'] in ['emacs','dumb']:
1687 raise EnvironmentError
1701 raise EnvironmentError
1688 xsys(pager_cmd + ' ' + fname)
1702 xsys(pager_cmd + ' ' + fname)
1689 except:
1703 except:
1690 try:
1704 try:
1691 if start > 0:
1705 if start > 0:
1692 start -= 1
1706 start -= 1
1693 page(open(fname).read(),start)
1707 page(open(fname).read(),start)
1694 except:
1708 except:
1695 print 'Unable to show file',`fname`
1709 print 'Unable to show file',`fname`
1696
1710
1697
1711
1698 #----------------------------------------------------------------------------
1712 #----------------------------------------------------------------------------
1699 def snip_print(str,width = 75,print_full = 0,header = ''):
1713 def snip_print(str,width = 75,print_full = 0,header = ''):
1700 """Print a string snipping the midsection to fit in width.
1714 """Print a string snipping the midsection to fit in width.
1701
1715
1702 print_full: mode control:
1716 print_full: mode control:
1703 - 0: only snip long strings
1717 - 0: only snip long strings
1704 - 1: send to page() directly.
1718 - 1: send to page() directly.
1705 - 2: snip long strings and ask for full length viewing with page()
1719 - 2: snip long strings and ask for full length viewing with page()
1706 Return 1 if snipping was necessary, 0 otherwise."""
1720 Return 1 if snipping was necessary, 0 otherwise."""
1707
1721
1708 if print_full == 1:
1722 if print_full == 1:
1709 page(header+str)
1723 page(header+str)
1710 return 0
1724 return 0
1711
1725
1712 print header,
1726 print header,
1713 if len(str) < width:
1727 if len(str) < width:
1714 print str
1728 print str
1715 snip = 0
1729 snip = 0
1716 else:
1730 else:
1717 whalf = int((width -5)/2)
1731 whalf = int((width -5)/2)
1718 print str[:whalf] + ' <...> ' + str[-whalf:]
1732 print str[:whalf] + ' <...> ' + str[-whalf:]
1719 snip = 1
1733 snip = 1
1720 if snip and print_full == 2:
1734 if snip and print_full == 2:
1721 if raw_input(header+' Snipped. View (y/n)? [N]').lower() == 'y':
1735 if raw_input(header+' Snipped. View (y/n)? [N]').lower() == 'y':
1722 page(str)
1736 page(str)
1723 return snip
1737 return snip
1724
1738
1725 #****************************************************************************
1739 #****************************************************************************
1726 # lists, dicts and structures
1740 # lists, dicts and structures
1727
1741
1728 def belong(candidates,checklist):
1742 def belong(candidates,checklist):
1729 """Check whether a list of items appear in a given list of options.
1743 """Check whether a list of items appear in a given list of options.
1730
1744
1731 Returns a list of 1 and 0, one for each candidate given."""
1745 Returns a list of 1 and 0, one for each candidate given."""
1732
1746
1733 return [x in checklist for x in candidates]
1747 return [x in checklist for x in candidates]
1734
1748
1735 #----------------------------------------------------------------------------
1749 #----------------------------------------------------------------------------
1736 def uniq_stable(elems):
1750 def uniq_stable(elems):
1737 """uniq_stable(elems) -> list
1751 """uniq_stable(elems) -> list
1738
1752
1739 Return from an iterable, a list of all the unique elements in the input,
1753 Return from an iterable, a list of all the unique elements in the input,
1740 but maintaining the order in which they first appear.
1754 but maintaining the order in which they first appear.
1741
1755
1742 A naive solution to this problem which just makes a dictionary with the
1756 A naive solution to this problem which just makes a dictionary with the
1743 elements as keys fails to respect the stability condition, since
1757 elements as keys fails to respect the stability condition, since
1744 dictionaries are unsorted by nature.
1758 dictionaries are unsorted by nature.
1745
1759
1746 Note: All elements in the input must be valid dictionary keys for this
1760 Note: All elements in the input must be valid dictionary keys for this
1747 routine to work, as it internally uses a dictionary for efficiency
1761 routine to work, as it internally uses a dictionary for efficiency
1748 reasons."""
1762 reasons."""
1749
1763
1750 unique = []
1764 unique = []
1751 unique_dict = {}
1765 unique_dict = {}
1752 for nn in elems:
1766 for nn in elems:
1753 if nn not in unique_dict:
1767 if nn not in unique_dict:
1754 unique.append(nn)
1768 unique.append(nn)
1755 unique_dict[nn] = None
1769 unique_dict[nn] = None
1756 return unique
1770 return unique
1757
1771
1758 #----------------------------------------------------------------------------
1772 #----------------------------------------------------------------------------
1759 class NLprinter:
1773 class NLprinter:
1760 """Print an arbitrarily nested list, indicating index numbers.
1774 """Print an arbitrarily nested list, indicating index numbers.
1761
1775
1762 An instance of this class called nlprint is available and callable as a
1776 An instance of this class called nlprint is available and callable as a
1763 function.
1777 function.
1764
1778
1765 nlprint(list,indent=' ',sep=': ') -> prints indenting each level by 'indent'
1779 nlprint(list,indent=' ',sep=': ') -> prints indenting each level by 'indent'
1766 and using 'sep' to separate the index from the value. """
1780 and using 'sep' to separate the index from the value. """
1767
1781
1768 def __init__(self):
1782 def __init__(self):
1769 self.depth = 0
1783 self.depth = 0
1770
1784
1771 def __call__(self,lst,pos='',**kw):
1785 def __call__(self,lst,pos='',**kw):
1772 """Prints the nested list numbering levels."""
1786 """Prints the nested list numbering levels."""
1773 kw.setdefault('indent',' ')
1787 kw.setdefault('indent',' ')
1774 kw.setdefault('sep',': ')
1788 kw.setdefault('sep',': ')
1775 kw.setdefault('start',0)
1789 kw.setdefault('start',0)
1776 kw.setdefault('stop',len(lst))
1790 kw.setdefault('stop',len(lst))
1777 # we need to remove start and stop from kw so they don't propagate
1791 # we need to remove start and stop from kw so they don't propagate
1778 # into a recursive call for a nested list.
1792 # into a recursive call for a nested list.
1779 start = kw['start']; del kw['start']
1793 start = kw['start']; del kw['start']
1780 stop = kw['stop']; del kw['stop']
1794 stop = kw['stop']; del kw['stop']
1781 if self.depth == 0 and 'header' in kw.keys():
1795 if self.depth == 0 and 'header' in kw.keys():
1782 print kw['header']
1796 print kw['header']
1783
1797
1784 for idx in range(start,stop):
1798 for idx in range(start,stop):
1785 elem = lst[idx]
1799 elem = lst[idx]
1786 if type(elem)==type([]):
1800 if type(elem)==type([]):
1787 self.depth += 1
1801 self.depth += 1
1788 self.__call__(elem,itpl('$pos$idx,'),**kw)
1802 self.__call__(elem,itpl('$pos$idx,'),**kw)
1789 self.depth -= 1
1803 self.depth -= 1
1790 else:
1804 else:
1791 printpl(kw['indent']*self.depth+'$pos$idx$kw["sep"]$elem')
1805 printpl(kw['indent']*self.depth+'$pos$idx$kw["sep"]$elem')
1792
1806
1793 nlprint = NLprinter()
1807 nlprint = NLprinter()
1794 #----------------------------------------------------------------------------
1808 #----------------------------------------------------------------------------
1795 def all_belong(candidates,checklist):
1809 def all_belong(candidates,checklist):
1796 """Check whether a list of items ALL appear in a given list of options.
1810 """Check whether a list of items ALL appear in a given list of options.
1797
1811
1798 Returns a single 1 or 0 value."""
1812 Returns a single 1 or 0 value."""
1799
1813
1800 return 1-(0 in [x in checklist for x in candidates])
1814 return 1-(0 in [x in checklist for x in candidates])
1801
1815
1802 #----------------------------------------------------------------------------
1816 #----------------------------------------------------------------------------
1803 def sort_compare(lst1,lst2,inplace = 1):
1817 def sort_compare(lst1,lst2,inplace = 1):
1804 """Sort and compare two lists.
1818 """Sort and compare two lists.
1805
1819
1806 By default it does it in place, thus modifying the lists. Use inplace = 0
1820 By default it does it in place, thus modifying the lists. Use inplace = 0
1807 to avoid that (at the cost of temporary copy creation)."""
1821 to avoid that (at the cost of temporary copy creation)."""
1808 if not inplace:
1822 if not inplace:
1809 lst1 = lst1[:]
1823 lst1 = lst1[:]
1810 lst2 = lst2[:]
1824 lst2 = lst2[:]
1811 lst1.sort(); lst2.sort()
1825 lst1.sort(); lst2.sort()
1812 return lst1 == lst2
1826 return lst1 == lst2
1813
1827
1814 #----------------------------------------------------------------------------
1828 #----------------------------------------------------------------------------
1815 def list2dict(lst):
1829 def list2dict(lst):
1816 """Takes a list of (key,value) pairs and turns it into a dict."""
1830 """Takes a list of (key,value) pairs and turns it into a dict."""
1817
1831
1818 dic = {}
1832 dic = {}
1819 for k,v in lst: dic[k] = v
1833 for k,v in lst: dic[k] = v
1820 return dic
1834 return dic
1821
1835
1822 #----------------------------------------------------------------------------
1836 #----------------------------------------------------------------------------
1823 def list2dict2(lst,default=''):
1837 def list2dict2(lst,default=''):
1824 """Takes a list and turns it into a dict.
1838 """Takes a list and turns it into a dict.
1825 Much slower than list2dict, but more versatile. This version can take
1839 Much slower than list2dict, but more versatile. This version can take
1826 lists with sublists of arbitrary length (including sclars)."""
1840 lists with sublists of arbitrary length (including sclars)."""
1827
1841
1828 dic = {}
1842 dic = {}
1829 for elem in lst:
1843 for elem in lst:
1830 if type(elem) in (types.ListType,types.TupleType):
1844 if type(elem) in (types.ListType,types.TupleType):
1831 size = len(elem)
1845 size = len(elem)
1832 if size == 0:
1846 if size == 0:
1833 pass
1847 pass
1834 elif size == 1:
1848 elif size == 1:
1835 dic[elem] = default
1849 dic[elem] = default
1836 else:
1850 else:
1837 k,v = elem[0], elem[1:]
1851 k,v = elem[0], elem[1:]
1838 if len(v) == 1: v = v[0]
1852 if len(v) == 1: v = v[0]
1839 dic[k] = v
1853 dic[k] = v
1840 else:
1854 else:
1841 dic[elem] = default
1855 dic[elem] = default
1842 return dic
1856 return dic
1843
1857
1844 #----------------------------------------------------------------------------
1858 #----------------------------------------------------------------------------
1845 def flatten(seq):
1859 def flatten(seq):
1846 """Flatten a list of lists (NOT recursive, only works for 2d lists)."""
1860 """Flatten a list of lists (NOT recursive, only works for 2d lists)."""
1847
1861
1848 return [x for subseq in seq for x in subseq]
1862 return [x for subseq in seq for x in subseq]
1849
1863
1850 #----------------------------------------------------------------------------
1864 #----------------------------------------------------------------------------
1851 def get_slice(seq,start=0,stop=None,step=1):
1865 def get_slice(seq,start=0,stop=None,step=1):
1852 """Get a slice of a sequence with variable step. Specify start,stop,step."""
1866 """Get a slice of a sequence with variable step. Specify start,stop,step."""
1853 if stop == None:
1867 if stop == None:
1854 stop = len(seq)
1868 stop = len(seq)
1855 item = lambda i: seq[i]
1869 item = lambda i: seq[i]
1856 return map(item,xrange(start,stop,step))
1870 return map(item,xrange(start,stop,step))
1857
1871
1858 #----------------------------------------------------------------------------
1872 #----------------------------------------------------------------------------
1859 def chop(seq,size):
1873 def chop(seq,size):
1860 """Chop a sequence into chunks of the given size."""
1874 """Chop a sequence into chunks of the given size."""
1861 chunk = lambda i: seq[i:i+size]
1875 chunk = lambda i: seq[i:i+size]
1862 return map(chunk,xrange(0,len(seq),size))
1876 return map(chunk,xrange(0,len(seq),size))
1863
1877
1864 #----------------------------------------------------------------------------
1878 #----------------------------------------------------------------------------
1865 # with is a keyword as of python 2.5, so this function is renamed to withobj
1879 # with is a keyword as of python 2.5, so this function is renamed to withobj
1866 # from its old 'with' name.
1880 # from its old 'with' name.
1867 def with_obj(object, **args):
1881 def with_obj(object, **args):
1868 """Set multiple attributes for an object, similar to Pascal's with.
1882 """Set multiple attributes for an object, similar to Pascal's with.
1869
1883
1870 Example:
1884 Example:
1871 with_obj(jim,
1885 with_obj(jim,
1872 born = 1960,
1886 born = 1960,
1873 haircolour = 'Brown',
1887 haircolour = 'Brown',
1874 eyecolour = 'Green')
1888 eyecolour = 'Green')
1875
1889
1876 Credit: Greg Ewing, in
1890 Credit: Greg Ewing, in
1877 http://mail.python.org/pipermail/python-list/2001-May/040703.html.
1891 http://mail.python.org/pipermail/python-list/2001-May/040703.html.
1878
1892
1879 NOTE: up until IPython 0.7.2, this was called simply 'with', but 'with'
1893 NOTE: up until IPython 0.7.2, this was called simply 'with', but 'with'
1880 has become a keyword for Python 2.5, so we had to rename it."""
1894 has become a keyword for Python 2.5, so we had to rename it."""
1881
1895
1882 object.__dict__.update(args)
1896 object.__dict__.update(args)
1883
1897
1884 #----------------------------------------------------------------------------
1898 #----------------------------------------------------------------------------
1885 def setattr_list(obj,alist,nspace = None):
1899 def setattr_list(obj,alist,nspace = None):
1886 """Set a list of attributes for an object taken from a namespace.
1900 """Set a list of attributes for an object taken from a namespace.
1887
1901
1888 setattr_list(obj,alist,nspace) -> sets in obj all the attributes listed in
1902 setattr_list(obj,alist,nspace) -> sets in obj all the attributes listed in
1889 alist with their values taken from nspace, which must be a dict (something
1903 alist with their values taken from nspace, which must be a dict (something
1890 like locals() will often do) If nspace isn't given, locals() of the
1904 like locals() will often do) If nspace isn't given, locals() of the
1891 *caller* is used, so in most cases you can omit it.
1905 *caller* is used, so in most cases you can omit it.
1892
1906
1893 Note that alist can be given as a string, which will be automatically
1907 Note that alist can be given as a string, which will be automatically
1894 split into a list on whitespace. If given as a list, it must be a list of
1908 split into a list on whitespace. If given as a list, it must be a list of
1895 *strings* (the variable names themselves), not of variables."""
1909 *strings* (the variable names themselves), not of variables."""
1896
1910
1897 # this grabs the local variables from the *previous* call frame -- that is
1911 # this grabs the local variables from the *previous* call frame -- that is
1898 # the locals from the function that called setattr_list().
1912 # the locals from the function that called setattr_list().
1899 # - snipped from weave.inline()
1913 # - snipped from weave.inline()
1900 if nspace is None:
1914 if nspace is None:
1901 call_frame = sys._getframe().f_back
1915 call_frame = sys._getframe().f_back
1902 nspace = call_frame.f_locals
1916 nspace = call_frame.f_locals
1903
1917
1904 if type(alist) in StringTypes:
1918 if type(alist) in StringTypes:
1905 alist = alist.split()
1919 alist = alist.split()
1906 for attr in alist:
1920 for attr in alist:
1907 val = eval(attr,nspace)
1921 val = eval(attr,nspace)
1908 setattr(obj,attr,val)
1922 setattr(obj,attr,val)
1909
1923
1910 #----------------------------------------------------------------------------
1924 #----------------------------------------------------------------------------
1911 def getattr_list(obj,alist,*args):
1925 def getattr_list(obj,alist,*args):
1912 """getattr_list(obj,alist[, default]) -> attribute list.
1926 """getattr_list(obj,alist[, default]) -> attribute list.
1913
1927
1914 Get a list of named attributes for an object. When a default argument is
1928 Get a list of named attributes for an object. When a default argument is
1915 given, it is returned when the attribute doesn't exist; without it, an
1929 given, it is returned when the attribute doesn't exist; without it, an
1916 exception is raised in that case.
1930 exception is raised in that case.
1917
1931
1918 Note that alist can be given as a string, which will be automatically
1932 Note that alist can be given as a string, which will be automatically
1919 split into a list on whitespace. If given as a list, it must be a list of
1933 split into a list on whitespace. If given as a list, it must be a list of
1920 *strings* (the variable names themselves), not of variables."""
1934 *strings* (the variable names themselves), not of variables."""
1921
1935
1922 if type(alist) in StringTypes:
1936 if type(alist) in StringTypes:
1923 alist = alist.split()
1937 alist = alist.split()
1924 if args:
1938 if args:
1925 if len(args)==1:
1939 if len(args)==1:
1926 default = args[0]
1940 default = args[0]
1927 return map(lambda attr: getattr(obj,attr,default),alist)
1941 return map(lambda attr: getattr(obj,attr,default),alist)
1928 else:
1942 else:
1929 raise ValueError,'getattr_list() takes only one optional argument'
1943 raise ValueError,'getattr_list() takes only one optional argument'
1930 else:
1944 else:
1931 return map(lambda attr: getattr(obj,attr),alist)
1945 return map(lambda attr: getattr(obj,attr),alist)
1932
1946
1933 #----------------------------------------------------------------------------
1947 #----------------------------------------------------------------------------
1934 def map_method(method,object_list,*argseq,**kw):
1948 def map_method(method,object_list,*argseq,**kw):
1935 """map_method(method,object_list,*args,**kw) -> list
1949 """map_method(method,object_list,*args,**kw) -> list
1936
1950
1937 Return a list of the results of applying the methods to the items of the
1951 Return a list of the results of applying the methods to the items of the
1938 argument sequence(s). If more than one sequence is given, the method is
1952 argument sequence(s). If more than one sequence is given, the method is
1939 called with an argument list consisting of the corresponding item of each
1953 called with an argument list consisting of the corresponding item of each
1940 sequence. All sequences must be of the same length.
1954 sequence. All sequences must be of the same length.
1941
1955
1942 Keyword arguments are passed verbatim to all objects called.
1956 Keyword arguments are passed verbatim to all objects called.
1943
1957
1944 This is Python code, so it's not nearly as fast as the builtin map()."""
1958 This is Python code, so it's not nearly as fast as the builtin map()."""
1945
1959
1946 out_list = []
1960 out_list = []
1947 idx = 0
1961 idx = 0
1948 for object in object_list:
1962 for object in object_list:
1949 try:
1963 try:
1950 handler = getattr(object, method)
1964 handler = getattr(object, method)
1951 except AttributeError:
1965 except AttributeError:
1952 out_list.append(None)
1966 out_list.append(None)
1953 else:
1967 else:
1954 if argseq:
1968 if argseq:
1955 args = map(lambda lst:lst[idx],argseq)
1969 args = map(lambda lst:lst[idx],argseq)
1956 #print 'ob',object,'hand',handler,'ar',args # dbg
1970 #print 'ob',object,'hand',handler,'ar',args # dbg
1957 out_list.append(handler(args,**kw))
1971 out_list.append(handler(args,**kw))
1958 else:
1972 else:
1959 out_list.append(handler(**kw))
1973 out_list.append(handler(**kw))
1960 idx += 1
1974 idx += 1
1961 return out_list
1975 return out_list
1962
1976
1963 #----------------------------------------------------------------------------
1977 #----------------------------------------------------------------------------
1964 def get_class_members(cls):
1978 def get_class_members(cls):
1965 ret = dir(cls)
1979 ret = dir(cls)
1966 if hasattr(cls,'__bases__'):
1980 if hasattr(cls,'__bases__'):
1967 for base in cls.__bases__:
1981 for base in cls.__bases__:
1968 ret.extend(get_class_members(base))
1982 ret.extend(get_class_members(base))
1969 return ret
1983 return ret
1970
1984
1971 #----------------------------------------------------------------------------
1985 #----------------------------------------------------------------------------
1972 def dir2(obj):
1986 def dir2(obj):
1973 """dir2(obj) -> list of strings
1987 """dir2(obj) -> list of strings
1974
1988
1975 Extended version of the Python builtin dir(), which does a few extra
1989 Extended version of the Python builtin dir(), which does a few extra
1976 checks, and supports common objects with unusual internals that confuse
1990 checks, and supports common objects with unusual internals that confuse
1977 dir(), such as Traits and PyCrust.
1991 dir(), such as Traits and PyCrust.
1978
1992
1979 This version is guaranteed to return only a list of true strings, whereas
1993 This version is guaranteed to return only a list of true strings, whereas
1980 dir() returns anything that objects inject into themselves, even if they
1994 dir() returns anything that objects inject into themselves, even if they
1981 are later not really valid for attribute access (many extension libraries
1995 are later not really valid for attribute access (many extension libraries
1982 have such bugs).
1996 have such bugs).
1983 """
1997 """
1984
1998
1985 # Start building the attribute list via dir(), and then complete it
1999 # Start building the attribute list via dir(), and then complete it
1986 # with a few extra special-purpose calls.
2000 # with a few extra special-purpose calls.
1987 words = dir(obj)
2001 words = dir(obj)
1988
2002
1989 if hasattr(obj,'__class__'):
2003 if hasattr(obj,'__class__'):
1990 words.append('__class__')
2004 words.append('__class__')
1991 words.extend(get_class_members(obj.__class__))
2005 words.extend(get_class_members(obj.__class__))
1992 #if '__base__' in words: 1/0
2006 #if '__base__' in words: 1/0
1993
2007
1994 # Some libraries (such as traits) may introduce duplicates, we want to
2008 # Some libraries (such as traits) may introduce duplicates, we want to
1995 # track and clean this up if it happens
2009 # track and clean this up if it happens
1996 may_have_dupes = False
2010 may_have_dupes = False
1997
2011
1998 # this is the 'dir' function for objects with Enthought's traits
2012 # this is the 'dir' function for objects with Enthought's traits
1999 if hasattr(obj, 'trait_names'):
2013 if hasattr(obj, 'trait_names'):
2000 try:
2014 try:
2001 words.extend(obj.trait_names())
2015 words.extend(obj.trait_names())
2002 may_have_dupes = True
2016 may_have_dupes = True
2003 except TypeError:
2017 except TypeError:
2004 # This will happen if `obj` is a class and not an instance.
2018 # This will happen if `obj` is a class and not an instance.
2005 pass
2019 pass
2006
2020
2007 # Support for PyCrust-style _getAttributeNames magic method.
2021 # Support for PyCrust-style _getAttributeNames magic method.
2008 if hasattr(obj, '_getAttributeNames'):
2022 if hasattr(obj, '_getAttributeNames'):
2009 try:
2023 try:
2010 words.extend(obj._getAttributeNames())
2024 words.extend(obj._getAttributeNames())
2011 may_have_dupes = True
2025 may_have_dupes = True
2012 except TypeError:
2026 except TypeError:
2013 # `obj` is a class and not an instance. Ignore
2027 # `obj` is a class and not an instance. Ignore
2014 # this error.
2028 # this error.
2015 pass
2029 pass
2016
2030
2017 if may_have_dupes:
2031 if may_have_dupes:
2018 # eliminate possible duplicates, as some traits may also
2032 # eliminate possible duplicates, as some traits may also
2019 # appear as normal attributes in the dir() call.
2033 # appear as normal attributes in the dir() call.
2020 words = list(set(words))
2034 words = list(set(words))
2021 words.sort()
2035 words.sort()
2022
2036
2023 # filter out non-string attributes which may be stuffed by dir() calls
2037 # filter out non-string attributes which may be stuffed by dir() calls
2024 # and poor coding in third-party modules
2038 # and poor coding in third-party modules
2025 return [w for w in words if isinstance(w, basestring)]
2039 return [w for w in words if isinstance(w, basestring)]
2026
2040
2027 #----------------------------------------------------------------------------
2041 #----------------------------------------------------------------------------
2028 def import_fail_info(mod_name,fns=None):
2042 def import_fail_info(mod_name,fns=None):
2029 """Inform load failure for a module."""
2043 """Inform load failure for a module."""
2030
2044
2031 if fns == None:
2045 if fns == None:
2032 warn("Loading of %s failed.\n" % (mod_name,))
2046 warn("Loading of %s failed.\n" % (mod_name,))
2033 else:
2047 else:
2034 warn("Loading of %s from %s failed.\n" % (fns,mod_name))
2048 warn("Loading of %s from %s failed.\n" % (fns,mod_name))
2035
2049
2036 #----------------------------------------------------------------------------
2050 #----------------------------------------------------------------------------
2037 # Proposed popitem() extension, written as a method
2051 # Proposed popitem() extension, written as a method
2038
2052
2039
2053
2040 class NotGiven: pass
2054 class NotGiven: pass
2041
2055
2042 def popkey(dct,key,default=NotGiven):
2056 def popkey(dct,key,default=NotGiven):
2043 """Return dct[key] and delete dct[key].
2057 """Return dct[key] and delete dct[key].
2044
2058
2045 If default is given, return it if dct[key] doesn't exist, otherwise raise
2059 If default is given, return it if dct[key] doesn't exist, otherwise raise
2046 KeyError. """
2060 KeyError. """
2047
2061
2048 try:
2062 try:
2049 val = dct[key]
2063 val = dct[key]
2050 except KeyError:
2064 except KeyError:
2051 if default is NotGiven:
2065 if default is NotGiven:
2052 raise
2066 raise
2053 else:
2067 else:
2054 return default
2068 return default
2055 else:
2069 else:
2056 del dct[key]
2070 del dct[key]
2057 return val
2071 return val
2058
2072
2059 def wrap_deprecated(func, suggest = '<nothing>'):
2073 def wrap_deprecated(func, suggest = '<nothing>'):
2060 def newFunc(*args, **kwargs):
2074 def newFunc(*args, **kwargs):
2061 warnings.warn("Call to deprecated function %s, use %s instead" %
2075 warnings.warn("Call to deprecated function %s, use %s instead" %
2062 ( func.__name__, suggest),
2076 ( func.__name__, suggest),
2063 category=DeprecationWarning,
2077 category=DeprecationWarning,
2064 stacklevel = 2)
2078 stacklevel = 2)
2065 return func(*args, **kwargs)
2079 return func(*args, **kwargs)
2066 return newFunc
2080 return newFunc
2067
2081
2068
2082
2069 def _num_cpus_unix():
2083 def _num_cpus_unix():
2070 """Return the number of active CPUs on a Unix system."""
2084 """Return the number of active CPUs on a Unix system."""
2071 return os.sysconf("SC_NPROCESSORS_ONLN")
2085 return os.sysconf("SC_NPROCESSORS_ONLN")
2072
2086
2073
2087
2074 def _num_cpus_darwin():
2088 def _num_cpus_darwin():
2075 """Return the number of active CPUs on a Darwin system."""
2089 """Return the number of active CPUs on a Darwin system."""
2076 p = subprocess.Popen(['sysctl','-n','hw.ncpu'],stdout=subprocess.PIPE)
2090 p = subprocess.Popen(['sysctl','-n','hw.ncpu'],stdout=subprocess.PIPE)
2077 return p.stdout.read()
2091 return p.stdout.read()
2078
2092
2079
2093
2080 def _num_cpus_windows():
2094 def _num_cpus_windows():
2081 """Return the number of active CPUs on a Windows system."""
2095 """Return the number of active CPUs on a Windows system."""
2082 return os.environ.get("NUMBER_OF_PROCESSORS")
2096 return os.environ.get("NUMBER_OF_PROCESSORS")
2083
2097
2084
2098
2085 def num_cpus():
2099 def num_cpus():
2086 """Return the effective number of CPUs in the system as an integer.
2100 """Return the effective number of CPUs in the system as an integer.
2087
2101
2088 This cross-platform function makes an attempt at finding the total number of
2102 This cross-platform function makes an attempt at finding the total number of
2089 available CPUs in the system, as returned by various underlying system and
2103 available CPUs in the system, as returned by various underlying system and
2090 python calls.
2104 python calls.
2091
2105
2092 If it can't find a sensible answer, it returns 1 (though an error *may* make
2106 If it can't find a sensible answer, it returns 1 (though an error *may* make
2093 it return a large positive number that's actually incorrect).
2107 it return a large positive number that's actually incorrect).
2094 """
2108 """
2095
2109
2096 # Many thanks to the Parallel Python project (http://www.parallelpython.com)
2110 # Many thanks to the Parallel Python project (http://www.parallelpython.com)
2097 # for the names of the keys we needed to look up for this function. This
2111 # for the names of the keys we needed to look up for this function. This
2098 # code was inspired by their equivalent function.
2112 # code was inspired by their equivalent function.
2099
2113
2100 ncpufuncs = {'Linux':_num_cpus_unix,
2114 ncpufuncs = {'Linux':_num_cpus_unix,
2101 'Darwin':_num_cpus_darwin,
2115 'Darwin':_num_cpus_darwin,
2102 'Windows':_num_cpus_windows,
2116 'Windows':_num_cpus_windows,
2103 # On Vista, python < 2.5.2 has a bug and returns 'Microsoft'
2117 # On Vista, python < 2.5.2 has a bug and returns 'Microsoft'
2104 # See http://bugs.python.org/issue1082 for details.
2118 # See http://bugs.python.org/issue1082 for details.
2105 'Microsoft':_num_cpus_windows,
2119 'Microsoft':_num_cpus_windows,
2106 }
2120 }
2107
2121
2108 ncpufunc = ncpufuncs.get(platform.system(),
2122 ncpufunc = ncpufuncs.get(platform.system(),
2109 # default to unix version (Solaris, AIX, etc)
2123 # default to unix version (Solaris, AIX, etc)
2110 _num_cpus_unix)
2124 _num_cpus_unix)
2111
2125
2112 try:
2126 try:
2113 ncpus = max(1,int(ncpufunc()))
2127 ncpus = max(1,int(ncpufunc()))
2114 except:
2128 except:
2115 ncpus = 1
2129 ncpus = 1
2116 return ncpus
2130 return ncpus
2117
2131
2118 #*************************** end of file <genutils.py> **********************
2132 #*************************** end of file <genutils.py> **********************
@@ -1,2686 +1,2698 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 Requires Python 2.3 or newer.
5 Requires Python 2.3 or newer.
6
6
7 This file contains all the classes and helper functions specific to IPython.
7 This file contains all the classes and helper functions specific to IPython.
8
8
9 """
9 """
10
10
11 #*****************************************************************************
11 #*****************************************************************************
12 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de> and
12 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de> and
13 # Copyright (C) 2001-2006 Fernando Perez. <fperez@colorado.edu>
13 # Copyright (C) 2001-2006 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 # Note: this code originally subclassed code.InteractiveConsole from the
18 # Note: this code originally subclassed code.InteractiveConsole from the
19 # Python standard library. Over time, all of that class has been copied
19 # Python standard library. Over time, all of that class has been copied
20 # verbatim here for modifications which could not be accomplished by
20 # verbatim here for modifications which could not be accomplished by
21 # subclassing. At this point, there are no dependencies at all on the code
21 # subclassing. At this point, there are no dependencies at all on the code
22 # module anymore (it is not even imported). The Python License (sec. 2)
22 # module anymore (it is not even imported). The Python License (sec. 2)
23 # allows for this, but it's always nice to acknowledge credit where credit is
23 # allows for this, but it's always nice to acknowledge credit where credit is
24 # due.
24 # due.
25 #*****************************************************************************
25 #*****************************************************************************
26
26
27 #****************************************************************************
27 #****************************************************************************
28 # Modules and globals
28 # Modules and globals
29
29
30 from IPython import Release
30 from IPython import Release
31 __author__ = '%s <%s>\n%s <%s>' % \
31 __author__ = '%s <%s>\n%s <%s>' % \
32 ( Release.authors['Janko'] + Release.authors['Fernando'] )
32 ( Release.authors['Janko'] + Release.authors['Fernando'] )
33 __license__ = Release.license
33 __license__ = Release.license
34 __version__ = Release.version
34 __version__ = Release.version
35
35
36 # Python standard modules
36 # Python standard modules
37 import __main__
37 import __main__
38 import __builtin__
38 import __builtin__
39 import StringIO
39 import StringIO
40 import bdb
40 import bdb
41 import cPickle as pickle
41 import cPickle as pickle
42 import codeop
42 import codeop
43 import exceptions
43 import exceptions
44 import glob
44 import glob
45 import inspect
45 import inspect
46 import keyword
46 import keyword
47 import new
47 import new
48 import os
48 import os
49 import pydoc
49 import pydoc
50 import re
50 import re
51 import shutil
51 import shutil
52 import string
52 import string
53 import sys
53 import sys
54 import tempfile
54 import tempfile
55 import traceback
55 import traceback
56 import types
56 import types
57 import warnings
57 import warnings
58 warnings.filterwarnings('ignore', r'.*sets module*')
58 warnings.filterwarnings('ignore', r'.*sets module*')
59 from sets import Set
59 from sets import Set
60 from pprint import pprint, pformat
60 from pprint import pprint, pformat
61
61
62 # IPython's own modules
62 # IPython's own modules
63 #import IPython
63 #import IPython
64 from IPython import Debugger,OInspect,PyColorize,ultraTB
64 from IPython import Debugger,OInspect,PyColorize,ultraTB
65 from IPython.ColorANSI import ColorScheme,ColorSchemeTable # too long names
65 from IPython.ColorANSI import ColorScheme,ColorSchemeTable # too long names
66 from IPython.Extensions import pickleshare
66 from IPython.Extensions import pickleshare
67 from IPython.FakeModule import FakeModule
67 from IPython.FakeModule import FakeModule
68 from IPython.Itpl import Itpl,itpl,printpl,ItplNS,itplns
68 from IPython.Itpl import Itpl,itpl,printpl,ItplNS,itplns
69 from IPython.Logger import Logger
69 from IPython.Logger import Logger
70 from IPython.Magic import Magic
70 from IPython.Magic import Magic
71 from IPython.Prompts import CachedOutput
71 from IPython.Prompts import CachedOutput
72 from IPython.ipstruct import Struct
72 from IPython.ipstruct import Struct
73 from IPython.background_jobs import BackgroundJobManager
73 from IPython.background_jobs import BackgroundJobManager
74 from IPython.usage import cmd_line_usage,interactive_usage
74 from IPython.usage import cmd_line_usage,interactive_usage
75 from IPython.genutils import *
75 from IPython.genutils import *
76 from IPython.strdispatch import StrDispatch
76 from IPython.strdispatch import StrDispatch
77 import IPython.ipapi
77 import IPython.ipapi
78 import IPython.history
78 import IPython.history
79 import IPython.prefilter as prefilter
79 import IPython.prefilter as prefilter
80 import IPython.shadowns
80 import IPython.shadowns
81 # Globals
81 # Globals
82
82
83 # store the builtin raw_input globally, and use this always, in case user code
83 # store the builtin raw_input globally, and use this always, in case user code
84 # overwrites it (like wx.py.PyShell does)
84 # overwrites it (like wx.py.PyShell does)
85 raw_input_original = raw_input
85 raw_input_original = raw_input
86
86
87 # compiled regexps for autoindent management
87 # compiled regexps for autoindent management
88 dedent_re = re.compile(r'^\s+raise|^\s+return|^\s+pass')
88 dedent_re = re.compile(r'^\s+raise|^\s+return|^\s+pass')
89
89
90
90
91 #****************************************************************************
91 #****************************************************************************
92 # Some utility function definitions
92 # Some utility function definitions
93
93
94 ini_spaces_re = re.compile(r'^(\s+)')
94 ini_spaces_re = re.compile(r'^(\s+)')
95
95
96 def num_ini_spaces(strng):
96 def num_ini_spaces(strng):
97 """Return the number of initial spaces in a string"""
97 """Return the number of initial spaces in a string"""
98
98
99 ini_spaces = ini_spaces_re.match(strng)
99 ini_spaces = ini_spaces_re.match(strng)
100 if ini_spaces:
100 if ini_spaces:
101 return ini_spaces.end()
101 return ini_spaces.end()
102 else:
102 else:
103 return 0
103 return 0
104
104
105 def softspace(file, newvalue):
105 def softspace(file, newvalue):
106 """Copied from code.py, to remove the dependency"""
106 """Copied from code.py, to remove the dependency"""
107
107
108 oldvalue = 0
108 oldvalue = 0
109 try:
109 try:
110 oldvalue = file.softspace
110 oldvalue = file.softspace
111 except AttributeError:
111 except AttributeError:
112 pass
112 pass
113 try:
113 try:
114 file.softspace = newvalue
114 file.softspace = newvalue
115 except (AttributeError, TypeError):
115 except (AttributeError, TypeError):
116 # "attribute-less object" or "read-only attributes"
116 # "attribute-less object" or "read-only attributes"
117 pass
117 pass
118 return oldvalue
118 return oldvalue
119
119
120
120
121 #****************************************************************************
121 #****************************************************************************
122 # Local use exceptions
122 # Local use exceptions
123 class SpaceInInput(exceptions.Exception): pass
123 class SpaceInInput(exceptions.Exception): pass
124
124
125
125
126 #****************************************************************************
126 #****************************************************************************
127 # Local use classes
127 # Local use classes
128 class Bunch: pass
128 class Bunch: pass
129
129
130 class Undefined: pass
130 class Undefined: pass
131
131
132 class Quitter(object):
132 class Quitter(object):
133 """Simple class to handle exit, similar to Python 2.5's.
133 """Simple class to handle exit, similar to Python 2.5's.
134
134
135 It handles exiting in an ipython-safe manner, which the one in Python 2.5
135 It handles exiting in an ipython-safe manner, which the one in Python 2.5
136 doesn't do (obviously, since it doesn't know about ipython)."""
136 doesn't do (obviously, since it doesn't know about ipython)."""
137
137
138 def __init__(self,shell,name):
138 def __init__(self,shell,name):
139 self.shell = shell
139 self.shell = shell
140 self.name = name
140 self.name = name
141
141
142 def __repr__(self):
142 def __repr__(self):
143 return 'Type %s() to exit.' % self.name
143 return 'Type %s() to exit.' % self.name
144 __str__ = __repr__
144 __str__ = __repr__
145
145
146 def __call__(self):
146 def __call__(self):
147 self.shell.exit()
147 self.shell.exit()
148
148
149 class InputList(list):
149 class InputList(list):
150 """Class to store user input.
150 """Class to store user input.
151
151
152 It's basically a list, but slices return a string instead of a list, thus
152 It's basically a list, but slices return a string instead of a list, thus
153 allowing things like (assuming 'In' is an instance):
153 allowing things like (assuming 'In' is an instance):
154
154
155 exec In[4:7]
155 exec In[4:7]
156
156
157 or
157 or
158
158
159 exec In[5:9] + In[14] + In[21:25]"""
159 exec In[5:9] + In[14] + In[21:25]"""
160
160
161 def __getslice__(self,i,j):
161 def __getslice__(self,i,j):
162 return ''.join(list.__getslice__(self,i,j))
162 return ''.join(list.__getslice__(self,i,j))
163
163
164 class SyntaxTB(ultraTB.ListTB):
164 class SyntaxTB(ultraTB.ListTB):
165 """Extension which holds some state: the last exception value"""
165 """Extension which holds some state: the last exception value"""
166
166
167 def __init__(self,color_scheme = 'NoColor'):
167 def __init__(self,color_scheme = 'NoColor'):
168 ultraTB.ListTB.__init__(self,color_scheme)
168 ultraTB.ListTB.__init__(self,color_scheme)
169 self.last_syntax_error = None
169 self.last_syntax_error = None
170
170
171 def __call__(self, etype, value, elist):
171 def __call__(self, etype, value, elist):
172 self.last_syntax_error = value
172 self.last_syntax_error = value
173 ultraTB.ListTB.__call__(self,etype,value,elist)
173 ultraTB.ListTB.__call__(self,etype,value,elist)
174
174
175 def clear_err_state(self):
175 def clear_err_state(self):
176 """Return the current error state and clear it"""
176 """Return the current error state and clear it"""
177 e = self.last_syntax_error
177 e = self.last_syntax_error
178 self.last_syntax_error = None
178 self.last_syntax_error = None
179 return e
179 return e
180
180
181 #****************************************************************************
181 #****************************************************************************
182 # Main IPython class
182 # Main IPython class
183
183
184 # FIXME: the Magic class is a mixin for now, and will unfortunately remain so
184 # FIXME: the Magic class is a mixin for now, and will unfortunately remain so
185 # until a full rewrite is made. I've cleaned all cross-class uses of
185 # until a full rewrite is made. I've cleaned all cross-class uses of
186 # attributes and methods, but too much user code out there relies on the
186 # attributes and methods, but too much user code out there relies on the
187 # equlity %foo == __IP.magic_foo, so I can't actually remove the mixin usage.
187 # equlity %foo == __IP.magic_foo, so I can't actually remove the mixin usage.
188 #
188 #
189 # But at least now, all the pieces have been separated and we could, in
189 # But at least now, all the pieces have been separated and we could, in
190 # principle, stop using the mixin. This will ease the transition to the
190 # principle, stop using the mixin. This will ease the transition to the
191 # chainsaw branch.
191 # chainsaw branch.
192
192
193 # For reference, the following is the list of 'self.foo' uses in the Magic
193 # For reference, the following is the list of 'self.foo' uses in the Magic
194 # class as of 2005-12-28. These are names we CAN'T use in the main ipython
194 # class as of 2005-12-28. These are names we CAN'T use in the main ipython
195 # class, to prevent clashes.
195 # class, to prevent clashes.
196
196
197 # ['self.__class__', 'self.__dict__', 'self._inspect', 'self._ofind',
197 # ['self.__class__', 'self.__dict__', 'self._inspect', 'self._ofind',
198 # 'self.arg_err', 'self.extract_input', 'self.format_', 'self.lsmagic',
198 # 'self.arg_err', 'self.extract_input', 'self.format_', 'self.lsmagic',
199 # 'self.magic_', 'self.options_table', 'self.parse', 'self.shell',
199 # 'self.magic_', 'self.options_table', 'self.parse', 'self.shell',
200 # 'self.value']
200 # 'self.value']
201
201
202 class InteractiveShell(object,Magic):
202 class InteractiveShell(object,Magic):
203 """An enhanced console for Python."""
203 """An enhanced console for Python."""
204
204
205 # class attribute to indicate whether the class supports threads or not.
205 # class attribute to indicate whether the class supports threads or not.
206 # Subclasses with thread support should override this as needed.
206 # Subclasses with thread support should override this as needed.
207 isthreaded = False
207 isthreaded = False
208
208
209 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
209 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
210 user_ns = None,user_global_ns=None,banner2='',
210 user_ns = None,user_global_ns=None,banner2='',
211 custom_exceptions=((),None),embedded=False):
211 custom_exceptions=((),None),embedded=False):
212
212
213 # log system
213 # log system
214 self.logger = Logger(self,logfname='ipython_log.py',logmode='rotate')
214 self.logger = Logger(self,logfname='ipython_log.py',logmode='rotate')
215
215
216 # some minimal strict typechecks. For some core data structures, I
216 # some minimal strict typechecks. For some core data structures, I
217 # want actual basic python types, not just anything that looks like
217 # want actual basic python types, not just anything that looks like
218 # one. This is especially true for namespaces.
218 # one. This is especially true for namespaces.
219 for ns in (user_ns,user_global_ns):
219 for ns in (user_ns,user_global_ns):
220 if ns is not None and type(ns) != types.DictType:
220 if ns is not None and type(ns) != types.DictType:
221 raise TypeError,'namespace must be a dictionary'
221 raise TypeError,'namespace must be a dictionary'
222 # Job manager (for jobs run as background threads)
222 # Job manager (for jobs run as background threads)
223 self.jobs = BackgroundJobManager()
223 self.jobs = BackgroundJobManager()
224
224
225 # Store the actual shell's name
225 # Store the actual shell's name
226 self.name = name
226 self.name = name
227 self.more = False
227 self.more = False
228
228
229 # We need to know whether the instance is meant for embedding, since
229 # We need to know whether the instance is meant for embedding, since
230 # global/local namespaces need to be handled differently in that case
230 # global/local namespaces need to be handled differently in that case
231 self.embedded = embedded
231 self.embedded = embedded
232 if embedded:
232 if embedded:
233 # Control variable so users can, from within the embedded instance,
233 # Control variable so users can, from within the embedded instance,
234 # permanently deactivate it.
234 # permanently deactivate it.
235 self.embedded_active = True
235 self.embedded_active = True
236
236
237 # command compiler
237 # command compiler
238 self.compile = codeop.CommandCompiler()
238 self.compile = codeop.CommandCompiler()
239
239
240 # User input buffer
240 # User input buffer
241 self.buffer = []
241 self.buffer = []
242
242
243 # Default name given in compilation of code
243 # Default name given in compilation of code
244 self.filename = '<ipython console>'
244 self.filename = '<ipython console>'
245
245
246 # Install our own quitter instead of the builtins. For python2.3-2.4,
246 # Install our own quitter instead of the builtins. For python2.3-2.4,
247 # this brings in behavior like 2.5, and for 2.5 it's identical.
247 # this brings in behavior like 2.5, and for 2.5 it's identical.
248 __builtin__.exit = Quitter(self,'exit')
248 __builtin__.exit = Quitter(self,'exit')
249 __builtin__.quit = Quitter(self,'quit')
249 __builtin__.quit = Quitter(self,'quit')
250
250
251 # Make an empty namespace, which extension writers can rely on both
251 # Make an empty namespace, which extension writers can rely on both
252 # existing and NEVER being used by ipython itself. This gives them a
252 # existing and NEVER being used by ipython itself. This gives them a
253 # convenient location for storing additional information and state
253 # convenient location for storing additional information and state
254 # their extensions may require, without fear of collisions with other
254 # their extensions may require, without fear of collisions with other
255 # ipython names that may develop later.
255 # ipython names that may develop later.
256 self.meta = Struct()
256 self.meta = Struct()
257
257
258 # Create the namespace where the user will operate. user_ns is
258 # Create the namespace where the user will operate. user_ns is
259 # normally the only one used, and it is passed to the exec calls as
259 # normally the only one used, and it is passed to the exec calls as
260 # the locals argument. But we do carry a user_global_ns namespace
260 # the locals argument. But we do carry a user_global_ns namespace
261 # given as the exec 'globals' argument, This is useful in embedding
261 # given as the exec 'globals' argument, This is useful in embedding
262 # situations where the ipython shell opens in a context where the
262 # situations where the ipython shell opens in a context where the
263 # distinction between locals and globals is meaningful.
263 # distinction between locals and globals is meaningful.
264
264
265 # FIXME. For some strange reason, __builtins__ is showing up at user
265 # FIXME. For some strange reason, __builtins__ is showing up at user
266 # level as a dict instead of a module. This is a manual fix, but I
266 # level as a dict instead of a module. This is a manual fix, but I
267 # should really track down where the problem is coming from. Alex
267 # should really track down where the problem is coming from. Alex
268 # Schmolck reported this problem first.
268 # Schmolck reported this problem first.
269
269
270 # A useful post by Alex Martelli on this topic:
270 # A useful post by Alex Martelli on this topic:
271 # Re: inconsistent value from __builtins__
271 # Re: inconsistent value from __builtins__
272 # Von: Alex Martelli <aleaxit@yahoo.com>
272 # Von: Alex Martelli <aleaxit@yahoo.com>
273 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
273 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
274 # Gruppen: comp.lang.python
274 # Gruppen: comp.lang.python
275
275
276 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
276 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
277 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
277 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
278 # > <type 'dict'>
278 # > <type 'dict'>
279 # > >>> print type(__builtins__)
279 # > >>> print type(__builtins__)
280 # > <type 'module'>
280 # > <type 'module'>
281 # > Is this difference in return value intentional?
281 # > Is this difference in return value intentional?
282
282
283 # Well, it's documented that '__builtins__' can be either a dictionary
283 # Well, it's documented that '__builtins__' can be either a dictionary
284 # or a module, and it's been that way for a long time. Whether it's
284 # or a module, and it's been that way for a long time. Whether it's
285 # intentional (or sensible), I don't know. In any case, the idea is
285 # intentional (or sensible), I don't know. In any case, the idea is
286 # that if you need to access the built-in namespace directly, you
286 # that if you need to access the built-in namespace directly, you
287 # should start with "import __builtin__" (note, no 's') which will
287 # should start with "import __builtin__" (note, no 's') which will
288 # definitely give you a module. Yeah, it's somewhat confusing:-(.
288 # definitely give you a module. Yeah, it's somewhat confusing:-(.
289
289
290 # These routines return properly built dicts as needed by the rest of
290 # These routines return properly built dicts as needed by the rest of
291 # the code, and can also be used by extension writers to generate
291 # the code, and can also be used by extension writers to generate
292 # properly initialized namespaces.
292 # properly initialized namespaces.
293 user_ns = IPython.ipapi.make_user_ns(user_ns)
293 user_ns = IPython.ipapi.make_user_ns(user_ns)
294 user_global_ns = IPython.ipapi.make_user_global_ns(user_global_ns)
294 user_global_ns = IPython.ipapi.make_user_global_ns(user_global_ns)
295
295
296 # Assign namespaces
296 # Assign namespaces
297 # This is the namespace where all normal user variables live
297 # This is the namespace where all normal user variables live
298 self.user_ns = user_ns
298 self.user_ns = user_ns
299 # Embedded instances require a separate namespace for globals.
299 # Embedded instances require a separate namespace for globals.
300 # Normally this one is unused by non-embedded instances.
300 # Normally this one is unused by non-embedded instances.
301 self.user_global_ns = user_global_ns
301 self.user_global_ns = user_global_ns
302 # A namespace to keep track of internal data structures to prevent
302 # A namespace to keep track of internal data structures to prevent
303 # them from cluttering user-visible stuff. Will be updated later
303 # them from cluttering user-visible stuff. Will be updated later
304 self.internal_ns = {}
304 self.internal_ns = {}
305
305
306 # Namespace of system aliases. Each entry in the alias
306 # Namespace of system aliases. Each entry in the alias
307 # table must be a 2-tuple of the form (N,name), where N is the number
307 # table must be a 2-tuple of the form (N,name), where N is the number
308 # of positional arguments of the alias.
308 # of positional arguments of the alias.
309 self.alias_table = {}
309 self.alias_table = {}
310
310
311 # A table holding all the namespaces IPython deals with, so that
311 # A table holding all the namespaces IPython deals with, so that
312 # introspection facilities can search easily.
312 # introspection facilities can search easily.
313 self.ns_table = {'user':user_ns,
313 self.ns_table = {'user':user_ns,
314 'user_global':user_global_ns,
314 'user_global':user_global_ns,
315 'alias':self.alias_table,
315 'alias':self.alias_table,
316 'internal':self.internal_ns,
316 'internal':self.internal_ns,
317 'builtin':__builtin__.__dict__
317 'builtin':__builtin__.__dict__
318 }
318 }
319 # The user namespace MUST have a pointer to the shell itself.
319 # The user namespace MUST have a pointer to the shell itself.
320 self.user_ns[name] = self
320 self.user_ns[name] = self
321
321
322 # We need to insert into sys.modules something that looks like a
322 # We need to insert into sys.modules something that looks like a
323 # module but which accesses the IPython namespace, for shelve and
323 # module but which accesses the IPython namespace, for shelve and
324 # pickle to work interactively. Normally they rely on getting
324 # pickle to work interactively. Normally they rely on getting
325 # everything out of __main__, but for embedding purposes each IPython
325 # everything out of __main__, but for embedding purposes each IPython
326 # instance has its own private namespace, so we can't go shoving
326 # instance has its own private namespace, so we can't go shoving
327 # everything into __main__.
327 # everything into __main__.
328
328
329 # note, however, that we should only do this for non-embedded
329 # note, however, that we should only do this for non-embedded
330 # ipythons, which really mimic the __main__.__dict__ with their own
330 # ipythons, which really mimic the __main__.__dict__ with their own
331 # namespace. Embedded instances, on the other hand, should not do
331 # namespace. Embedded instances, on the other hand, should not do
332 # this because they need to manage the user local/global namespaces
332 # this because they need to manage the user local/global namespaces
333 # only, but they live within a 'normal' __main__ (meaning, they
333 # only, but they live within a 'normal' __main__ (meaning, they
334 # shouldn't overtake the execution environment of the script they're
334 # shouldn't overtake the execution environment of the script they're
335 # embedded in).
335 # embedded in).
336
336
337 if not embedded:
337 if not embedded:
338 try:
338 try:
339 main_name = self.user_ns['__name__']
339 main_name = self.user_ns['__name__']
340 except KeyError:
340 except KeyError:
341 raise KeyError,'user_ns dictionary MUST have a "__name__" key'
341 raise KeyError,'user_ns dictionary MUST have a "__name__" key'
342 else:
342 else:
343 #print "pickle hack in place" # dbg
343 #print "pickle hack in place" # dbg
344 #print 'main_name:',main_name # dbg
344 #print 'main_name:',main_name # dbg
345 sys.modules[main_name] = FakeModule(self.user_ns)
345 sys.modules[main_name] = FakeModule(self.user_ns)
346
346
347 # Now that FakeModule produces a real module, we've run into a nasty
347 # Now that FakeModule produces a real module, we've run into a nasty
348 # problem: after script execution (via %run), the module where the user
348 # problem: after script execution (via %run), the module where the user
349 # code ran is deleted. Now that this object is a true module (needed
349 # code ran is deleted. Now that this object is a true module (needed
350 # so docetst and other tools work correctly), the Python module
350 # so docetst and other tools work correctly), the Python module
351 # teardown mechanism runs over it, and sets to None every variable
351 # teardown mechanism runs over it, and sets to None every variable
352 # present in that module. This means that later calls to functions
352 # present in that module. This means that later calls to functions
353 # defined in the script (which have become interactively visible after
353 # defined in the script (which have become interactively visible after
354 # script exit) fail, because they hold references to objects that have
354 # script exit) fail, because they hold references to objects that have
355 # become overwritten into None. The only solution I see right now is
355 # become overwritten into None. The only solution I see right now is
356 # to protect every FakeModule used by %run by holding an internal
356 # to protect every FakeModule used by %run by holding an internal
357 # reference to it. This private list will be used for that. The
357 # reference to it. This private list will be used for that. The
358 # %reset command will flush it as well.
358 # %reset command will flush it as well.
359 self._user_main_modules = []
359 self._user_main_modules = []
360
360
361 # List of input with multi-line handling.
361 # List of input with multi-line handling.
362 # Fill its zero entry, user counter starts at 1
362 # Fill its zero entry, user counter starts at 1
363 self.input_hist = InputList(['\n'])
363 self.input_hist = InputList(['\n'])
364 # This one will hold the 'raw' input history, without any
364 # This one will hold the 'raw' input history, without any
365 # pre-processing. This will allow users to retrieve the input just as
365 # pre-processing. This will allow users to retrieve the input just as
366 # it was exactly typed in by the user, with %hist -r.
366 # it was exactly typed in by the user, with %hist -r.
367 self.input_hist_raw = InputList(['\n'])
367 self.input_hist_raw = InputList(['\n'])
368
368
369 # list of visited directories
369 # list of visited directories
370 try:
370 try:
371 self.dir_hist = [os.getcwd()]
371 self.dir_hist = [os.getcwd()]
372 except OSError:
372 except OSError:
373 self.dir_hist = []
373 self.dir_hist = []
374
374
375 # dict of output history
375 # dict of output history
376 self.output_hist = {}
376 self.output_hist = {}
377
377
378 # Get system encoding at startup time. Certain terminals (like Emacs
378 # Get system encoding at startup time. Certain terminals (like Emacs
379 # under Win32 have it set to None, and we need to have a known valid
379 # under Win32 have it set to None, and we need to have a known valid
380 # encoding to use in the raw_input() method
380 # encoding to use in the raw_input() method
381 try:
381 try:
382 self.stdin_encoding = sys.stdin.encoding or 'ascii'
382 self.stdin_encoding = sys.stdin.encoding or 'ascii'
383 except AttributeError:
383 except AttributeError:
384 self.stdin_encoding = 'ascii'
384 self.stdin_encoding = 'ascii'
385
385
386 # dict of things NOT to alias (keywords, builtins and some magics)
386 # dict of things NOT to alias (keywords, builtins and some magics)
387 no_alias = {}
387 no_alias = {}
388 no_alias_magics = ['cd','popd','pushd','dhist','alias','unalias']
388 no_alias_magics = ['cd','popd','pushd','dhist','alias','unalias']
389 for key in keyword.kwlist + no_alias_magics:
389 for key in keyword.kwlist + no_alias_magics:
390 no_alias[key] = 1
390 no_alias[key] = 1
391 no_alias.update(__builtin__.__dict__)
391 no_alias.update(__builtin__.__dict__)
392 self.no_alias = no_alias
392 self.no_alias = no_alias
393
393
394 # make global variables for user access to these
394 # make global variables for user access to these
395 self.user_ns['_ih'] = self.input_hist
395 self.user_ns['_ih'] = self.input_hist
396 self.user_ns['_oh'] = self.output_hist
396 self.user_ns['_oh'] = self.output_hist
397 self.user_ns['_dh'] = self.dir_hist
397 self.user_ns['_dh'] = self.dir_hist
398
398
399 # user aliases to input and output histories
399 # user aliases to input and output histories
400 self.user_ns['In'] = self.input_hist
400 self.user_ns['In'] = self.input_hist
401 self.user_ns['Out'] = self.output_hist
401 self.user_ns['Out'] = self.output_hist
402
402
403 self.user_ns['_sh'] = IPython.shadowns
403 self.user_ns['_sh'] = IPython.shadowns
404 # Object variable to store code object waiting execution. This is
404 # Object variable to store code object waiting execution. This is
405 # used mainly by the multithreaded shells, but it can come in handy in
405 # used mainly by the multithreaded shells, but it can come in handy in
406 # other situations. No need to use a Queue here, since it's a single
406 # other situations. No need to use a Queue here, since it's a single
407 # item which gets cleared once run.
407 # item which gets cleared once run.
408 self.code_to_run = None
408 self.code_to_run = None
409
409
410 # escapes for automatic behavior on the command line
410 # escapes for automatic behavior on the command line
411 self.ESC_SHELL = '!'
411 self.ESC_SHELL = '!'
412 self.ESC_SH_CAP = '!!'
412 self.ESC_SH_CAP = '!!'
413 self.ESC_HELP = '?'
413 self.ESC_HELP = '?'
414 self.ESC_MAGIC = '%'
414 self.ESC_MAGIC = '%'
415 self.ESC_QUOTE = ','
415 self.ESC_QUOTE = ','
416 self.ESC_QUOTE2 = ';'
416 self.ESC_QUOTE2 = ';'
417 self.ESC_PAREN = '/'
417 self.ESC_PAREN = '/'
418
418
419 # And their associated handlers
419 # And their associated handlers
420 self.esc_handlers = {self.ESC_PAREN : self.handle_auto,
420 self.esc_handlers = {self.ESC_PAREN : self.handle_auto,
421 self.ESC_QUOTE : self.handle_auto,
421 self.ESC_QUOTE : self.handle_auto,
422 self.ESC_QUOTE2 : self.handle_auto,
422 self.ESC_QUOTE2 : self.handle_auto,
423 self.ESC_MAGIC : self.handle_magic,
423 self.ESC_MAGIC : self.handle_magic,
424 self.ESC_HELP : self.handle_help,
424 self.ESC_HELP : self.handle_help,
425 self.ESC_SHELL : self.handle_shell_escape,
425 self.ESC_SHELL : self.handle_shell_escape,
426 self.ESC_SH_CAP : self.handle_shell_escape,
426 self.ESC_SH_CAP : self.handle_shell_escape,
427 }
427 }
428
428
429 # class initializations
429 # class initializations
430 Magic.__init__(self,self)
430 Magic.__init__(self,self)
431
431
432 # Python source parser/formatter for syntax highlighting
432 # Python source parser/formatter for syntax highlighting
433 pyformat = PyColorize.Parser().format
433 pyformat = PyColorize.Parser().format
434 self.pycolorize = lambda src: pyformat(src,'str',self.rc['colors'])
434 self.pycolorize = lambda src: pyformat(src,'str',self.rc['colors'])
435
435
436 # hooks holds pointers used for user-side customizations
436 # hooks holds pointers used for user-side customizations
437 self.hooks = Struct()
437 self.hooks = Struct()
438
438
439 self.strdispatchers = {}
439 self.strdispatchers = {}
440
440
441 # Set all default hooks, defined in the IPython.hooks module.
441 # Set all default hooks, defined in the IPython.hooks module.
442 hooks = IPython.hooks
442 hooks = IPython.hooks
443 for hook_name in hooks.__all__:
443 for hook_name in hooks.__all__:
444 # default hooks have priority 100, i.e. low; user hooks should have
444 # default hooks have priority 100, i.e. low; user hooks should have
445 # 0-100 priority
445 # 0-100 priority
446 self.set_hook(hook_name,getattr(hooks,hook_name), 100)
446 self.set_hook(hook_name,getattr(hooks,hook_name), 100)
447 #print "bound hook",hook_name
447 #print "bound hook",hook_name
448
448
449 # Flag to mark unconditional exit
449 # Flag to mark unconditional exit
450 self.exit_now = False
450 self.exit_now = False
451
451
452 self.usage_min = """\
452 self.usage_min = """\
453 An enhanced console for Python.
453 An enhanced console for Python.
454 Some of its features are:
454 Some of its features are:
455 - Readline support if the readline library is present.
455 - Readline support if the readline library is present.
456 - Tab completion in the local namespace.
456 - Tab completion in the local namespace.
457 - Logging of input, see command-line options.
457 - Logging of input, see command-line options.
458 - System shell escape via ! , eg !ls.
458 - System shell escape via ! , eg !ls.
459 - Magic commands, starting with a % (like %ls, %pwd, %cd, etc.)
459 - Magic commands, starting with a % (like %ls, %pwd, %cd, etc.)
460 - Keeps track of locally defined variables via %who, %whos.
460 - Keeps track of locally defined variables via %who, %whos.
461 - Show object information with a ? eg ?x or x? (use ?? for more info).
461 - Show object information with a ? eg ?x or x? (use ?? for more info).
462 """
462 """
463 if usage: self.usage = usage
463 if usage: self.usage = usage
464 else: self.usage = self.usage_min
464 else: self.usage = self.usage_min
465
465
466 # Storage
466 # Storage
467 self.rc = rc # This will hold all configuration information
467 self.rc = rc # This will hold all configuration information
468 self.pager = 'less'
468 self.pager = 'less'
469 # temporary files used for various purposes. Deleted at exit.
469 # temporary files used for various purposes. Deleted at exit.
470 self.tempfiles = []
470 self.tempfiles = []
471
471
472 # Keep track of readline usage (later set by init_readline)
472 # Keep track of readline usage (later set by init_readline)
473 self.has_readline = False
473 self.has_readline = False
474
474
475 # template for logfile headers. It gets resolved at runtime by the
475 # template for logfile headers. It gets resolved at runtime by the
476 # logstart method.
476 # logstart method.
477 self.loghead_tpl = \
477 self.loghead_tpl = \
478 """#log# Automatic Logger file. *** THIS MUST BE THE FIRST LINE ***
478 """#log# Automatic Logger file. *** THIS MUST BE THE FIRST LINE ***
479 #log# DO NOT CHANGE THIS LINE OR THE TWO BELOW
479 #log# DO NOT CHANGE THIS LINE OR THE TWO BELOW
480 #log# opts = %s
480 #log# opts = %s
481 #log# args = %s
481 #log# args = %s
482 #log# It is safe to make manual edits below here.
482 #log# It is safe to make manual edits below here.
483 #log#-----------------------------------------------------------------------
483 #log#-----------------------------------------------------------------------
484 """
484 """
485 # for pushd/popd management
485 # for pushd/popd management
486 try:
486 try:
487 self.home_dir = get_home_dir()
487 self.home_dir = get_home_dir()
488 except HomeDirError,msg:
488 except HomeDirError,msg:
489 fatal(msg)
489 fatal(msg)
490
490
491 self.dir_stack = []
491 self.dir_stack = []
492
492
493 # Functions to call the underlying shell.
493 # Functions to call the underlying shell.
494
494
495 # The first is similar to os.system, but it doesn't return a value,
495 # The first is similar to os.system, but it doesn't return a value,
496 # and it allows interpolation of variables in the user's namespace.
496 # and it allows interpolation of variables in the user's namespace.
497 self.system = lambda cmd: \
497 self.system = lambda cmd: \
498 self.hooks.shell_hook(self.var_expand(cmd,depth=2))
498 self.hooks.shell_hook(self.var_expand(cmd,depth=2))
499
499
500 # These are for getoutput and getoutputerror:
500 # These are for getoutput and getoutputerror:
501 self.getoutput = lambda cmd: \
501 self.getoutput = lambda cmd: \
502 getoutput(self.var_expand(cmd,depth=2),
502 getoutput(self.var_expand(cmd,depth=2),
503 header=self.rc.system_header,
503 header=self.rc.system_header,
504 verbose=self.rc.system_verbose)
504 verbose=self.rc.system_verbose)
505
505
506 self.getoutputerror = lambda cmd: \
506 self.getoutputerror = lambda cmd: \
507 getoutputerror(self.var_expand(cmd,depth=2),
507 getoutputerror(self.var_expand(cmd,depth=2),
508 header=self.rc.system_header,
508 header=self.rc.system_header,
509 verbose=self.rc.system_verbose)
509 verbose=self.rc.system_verbose)
510
510
511
511
512 # keep track of where we started running (mainly for crash post-mortem)
512 # keep track of where we started running (mainly for crash post-mortem)
513 self.starting_dir = os.getcwd()
513 self.starting_dir = os.getcwd()
514
514
515 # Various switches which can be set
515 # Various switches which can be set
516 self.CACHELENGTH = 5000 # this is cheap, it's just text
516 self.CACHELENGTH = 5000 # this is cheap, it's just text
517 self.BANNER = "Python %(version)s on %(platform)s\n" % sys.__dict__
517 self.BANNER = "Python %(version)s on %(platform)s\n" % sys.__dict__
518 self.banner2 = banner2
518 self.banner2 = banner2
519
519
520 # TraceBack handlers:
520 # TraceBack handlers:
521
521
522 # Syntax error handler.
522 # Syntax error handler.
523 self.SyntaxTB = SyntaxTB(color_scheme='NoColor')
523 self.SyntaxTB = SyntaxTB(color_scheme='NoColor')
524
524
525 # The interactive one is initialized with an offset, meaning we always
525 # The interactive one is initialized with an offset, meaning we always
526 # want to remove the topmost item in the traceback, which is our own
526 # want to remove the topmost item in the traceback, which is our own
527 # internal code. Valid modes: ['Plain','Context','Verbose']
527 # internal code. Valid modes: ['Plain','Context','Verbose']
528 self.InteractiveTB = ultraTB.AutoFormattedTB(mode = 'Plain',
528 self.InteractiveTB = ultraTB.AutoFormattedTB(mode = 'Plain',
529 color_scheme='NoColor',
529 color_scheme='NoColor',
530 tb_offset = 1)
530 tb_offset = 1)
531
531
532 # IPython itself shouldn't crash. This will produce a detailed
532 # IPython itself shouldn't crash. This will produce a detailed
533 # post-mortem if it does. But we only install the crash handler for
533 # post-mortem if it does. But we only install the crash handler for
534 # non-threaded shells, the threaded ones use a normal verbose reporter
534 # non-threaded shells, the threaded ones use a normal verbose reporter
535 # and lose the crash handler. This is because exceptions in the main
535 # and lose the crash handler. This is because exceptions in the main
536 # thread (such as in GUI code) propagate directly to sys.excepthook,
536 # thread (such as in GUI code) propagate directly to sys.excepthook,
537 # and there's no point in printing crash dumps for every user exception.
537 # and there's no point in printing crash dumps for every user exception.
538 if self.isthreaded:
538 if self.isthreaded:
539 ipCrashHandler = ultraTB.FormattedTB()
539 ipCrashHandler = ultraTB.FormattedTB()
540 else:
540 else:
541 from IPython import CrashHandler
541 from IPython import CrashHandler
542 ipCrashHandler = CrashHandler.IPythonCrashHandler(self)
542 ipCrashHandler = CrashHandler.IPythonCrashHandler(self)
543 self.set_crash_handler(ipCrashHandler)
543 self.set_crash_handler(ipCrashHandler)
544
544
545 # and add any custom exception handlers the user may have specified
545 # and add any custom exception handlers the user may have specified
546 self.set_custom_exc(*custom_exceptions)
546 self.set_custom_exc(*custom_exceptions)
547
547
548 # indentation management
548 # indentation management
549 self.autoindent = False
549 self.autoindent = False
550 self.indent_current_nsp = 0
550 self.indent_current_nsp = 0
551
551
552 # Make some aliases automatically
552 # Make some aliases automatically
553 # Prepare list of shell aliases to auto-define
553 # Prepare list of shell aliases to auto-define
554 if os.name == 'posix':
554 if os.name == 'posix':
555 auto_alias = ('mkdir mkdir', 'rmdir rmdir',
555 auto_alias = ('mkdir mkdir', 'rmdir rmdir',
556 'mv mv -i','rm rm -i','cp cp -i',
556 'mv mv -i','rm rm -i','cp cp -i',
557 'cat cat','less less','clear clear',
557 'cat cat','less less','clear clear',
558 # a better ls
558 # a better ls
559 'ls ls -F',
559 'ls ls -F',
560 # long ls
560 # long ls
561 'll ls -lF')
561 'll ls -lF')
562 # Extra ls aliases with color, which need special treatment on BSD
562 # Extra ls aliases with color, which need special treatment on BSD
563 # variants
563 # variants
564 ls_extra = ( # color ls
564 ls_extra = ( # color ls
565 'lc ls -F -o --color',
565 'lc ls -F -o --color',
566 # ls normal files only
566 # ls normal files only
567 'lf ls -F -o --color %l | grep ^-',
567 'lf ls -F -o --color %l | grep ^-',
568 # ls symbolic links
568 # ls symbolic links
569 'lk ls -F -o --color %l | grep ^l',
569 'lk ls -F -o --color %l | grep ^l',
570 # directories or links to directories,
570 # directories or links to directories,
571 'ldir ls -F -o --color %l | grep /$',
571 'ldir ls -F -o --color %l | grep /$',
572 # things which are executable
572 # things which are executable
573 'lx ls -F -o --color %l | grep ^-..x',
573 'lx ls -F -o --color %l | grep ^-..x',
574 )
574 )
575 # The BSDs don't ship GNU ls, so they don't understand the
575 # The BSDs don't ship GNU ls, so they don't understand the
576 # --color switch out of the box
576 # --color switch out of the box
577 if 'bsd' in sys.platform:
577 if 'bsd' in sys.platform:
578 ls_extra = ( # ls normal files only
578 ls_extra = ( # ls normal files only
579 'lf ls -lF | grep ^-',
579 'lf ls -lF | grep ^-',
580 # ls symbolic links
580 # ls symbolic links
581 'lk ls -lF | grep ^l',
581 'lk ls -lF | grep ^l',
582 # directories or links to directories,
582 # directories or links to directories,
583 'ldir ls -lF | grep /$',
583 'ldir ls -lF | grep /$',
584 # things which are executable
584 # things which are executable
585 'lx ls -lF | grep ^-..x',
585 'lx ls -lF | grep ^-..x',
586 )
586 )
587 auto_alias = auto_alias + ls_extra
587 auto_alias = auto_alias + ls_extra
588 elif os.name in ['nt','dos']:
588 elif os.name in ['nt','dos']:
589 auto_alias = ('ls dir /on',
589 auto_alias = ('ls dir /on',
590 'ddir dir /ad /on', 'ldir dir /ad /on',
590 'ddir dir /ad /on', 'ldir dir /ad /on',
591 'mkdir mkdir','rmdir rmdir','echo echo',
591 'mkdir mkdir','rmdir rmdir','echo echo',
592 'ren ren','cls cls','copy copy')
592 'ren ren','cls cls','copy copy')
593 else:
593 else:
594 auto_alias = ()
594 auto_alias = ()
595 self.auto_alias = [s.split(None,1) for s in auto_alias]
595 self.auto_alias = [s.split(None,1) for s in auto_alias]
596
596
597
597
598 # Produce a public API instance
598 # Produce a public API instance
599 self.api = IPython.ipapi.IPApi(self)
599 self.api = IPython.ipapi.IPApi(self)
600
600
601 # Call the actual (public) initializer
601 # Call the actual (public) initializer
602 self.init_auto_alias()
602 self.init_auto_alias()
603
603
604 # track which builtins we add, so we can clean up later
604 # track which builtins we add, so we can clean up later
605 self.builtins_added = {}
605 self.builtins_added = {}
606 # This method will add the necessary builtins for operation, but
606 # This method will add the necessary builtins for operation, but
607 # tracking what it did via the builtins_added dict.
607 # tracking what it did via the builtins_added dict.
608
608
609 #TODO: remove this, redundant
609 #TODO: remove this, redundant
610 self.add_builtins()
610 self.add_builtins()
611
611
612
612
613
613
614
614
615 # end __init__
615 # end __init__
616
616
617 def var_expand(self,cmd,depth=0):
617 def var_expand(self,cmd,depth=0):
618 """Expand python variables in a string.
618 """Expand python variables in a string.
619
619
620 The depth argument indicates how many frames above the caller should
620 The depth argument indicates how many frames above the caller should
621 be walked to look for the local namespace where to expand variables.
621 be walked to look for the local namespace where to expand variables.
622
622
623 The global namespace for expansion is always the user's interactive
623 The global namespace for expansion is always the user's interactive
624 namespace.
624 namespace.
625 """
625 """
626
626
627 return str(ItplNS(cmd,
627 return str(ItplNS(cmd,
628 self.user_ns, # globals
628 self.user_ns, # globals
629 # Skip our own frame in searching for locals:
629 # Skip our own frame in searching for locals:
630 sys._getframe(depth+1).f_locals # locals
630 sys._getframe(depth+1).f_locals # locals
631 ))
631 ))
632
632
633 def pre_config_initialization(self):
633 def pre_config_initialization(self):
634 """Pre-configuration init method
634 """Pre-configuration init method
635
635
636 This is called before the configuration files are processed to
636 This is called before the configuration files are processed to
637 prepare the services the config files might need.
637 prepare the services the config files might need.
638
638
639 self.rc already has reasonable default values at this point.
639 self.rc already has reasonable default values at this point.
640 """
640 """
641 rc = self.rc
641 rc = self.rc
642 try:
642 try:
643 self.db = pickleshare.PickleShareDB(rc.ipythondir + "/db")
643 self.db = pickleshare.PickleShareDB(rc.ipythondir + "/db")
644 except exceptions.UnicodeDecodeError:
644 except exceptions.UnicodeDecodeError:
645 print "Your ipythondir can't be decoded to unicode!"
645 print "Your ipythondir can't be decoded to unicode!"
646 print "Please set HOME environment variable to something that"
646 print "Please set HOME environment variable to something that"
647 print r"only has ASCII characters, e.g. c:\home"
647 print r"only has ASCII characters, e.g. c:\home"
648 print "Now it is",rc.ipythondir
648 print "Now it is",rc.ipythondir
649 sys.exit()
649 sys.exit()
650 self.shadowhist = IPython.history.ShadowHist(self.db)
650 self.shadowhist = IPython.history.ShadowHist(self.db)
651
651
652
652
653 def post_config_initialization(self):
653 def post_config_initialization(self):
654 """Post configuration init method
654 """Post configuration init method
655
655
656 This is called after the configuration files have been processed to
656 This is called after the configuration files have been processed to
657 'finalize' the initialization."""
657 'finalize' the initialization."""
658
658
659 rc = self.rc
659 rc = self.rc
660
660
661 # Object inspector
661 # Object inspector
662 self.inspector = OInspect.Inspector(OInspect.InspectColors,
662 self.inspector = OInspect.Inspector(OInspect.InspectColors,
663 PyColorize.ANSICodeColors,
663 PyColorize.ANSICodeColors,
664 'NoColor',
664 'NoColor',
665 rc.object_info_string_level)
665 rc.object_info_string_level)
666
666
667 self.rl_next_input = None
667 self.rl_next_input = None
668 self.rl_do_indent = False
668 self.rl_do_indent = False
669 # Load readline proper
669 # Load readline proper
670 if rc.readline:
670 if rc.readline:
671 self.init_readline()
671 self.init_readline()
672
672
673
673
674 # local shortcut, this is used a LOT
674 # local shortcut, this is used a LOT
675 self.log = self.logger.log
675 self.log = self.logger.log
676
676
677 # Initialize cache, set in/out prompts and printing system
677 # Initialize cache, set in/out prompts and printing system
678 self.outputcache = CachedOutput(self,
678 self.outputcache = CachedOutput(self,
679 rc.cache_size,
679 rc.cache_size,
680 rc.pprint,
680 rc.pprint,
681 input_sep = rc.separate_in,
681 input_sep = rc.separate_in,
682 output_sep = rc.separate_out,
682 output_sep = rc.separate_out,
683 output_sep2 = rc.separate_out2,
683 output_sep2 = rc.separate_out2,
684 ps1 = rc.prompt_in1,
684 ps1 = rc.prompt_in1,
685 ps2 = rc.prompt_in2,
685 ps2 = rc.prompt_in2,
686 ps_out = rc.prompt_out,
686 ps_out = rc.prompt_out,
687 pad_left = rc.prompts_pad_left)
687 pad_left = rc.prompts_pad_left)
688
688
689 # user may have over-ridden the default print hook:
689 # user may have over-ridden the default print hook:
690 try:
690 try:
691 self.outputcache.__class__.display = self.hooks.display
691 self.outputcache.__class__.display = self.hooks.display
692 except AttributeError:
692 except AttributeError:
693 pass
693 pass
694
694
695 # I don't like assigning globally to sys, because it means when
695 # I don't like assigning globally to sys, because it means when
696 # embedding instances, each embedded instance overrides the previous
696 # embedding instances, each embedded instance overrides the previous
697 # choice. But sys.displayhook seems to be called internally by exec,
697 # choice. But sys.displayhook seems to be called internally by exec,
698 # so I don't see a way around it. We first save the original and then
698 # so I don't see a way around it. We first save the original and then
699 # overwrite it.
699 # overwrite it.
700 self.sys_displayhook = sys.displayhook
700 self.sys_displayhook = sys.displayhook
701 sys.displayhook = self.outputcache
701 sys.displayhook = self.outputcache
702
702
703 # Do a proper resetting of doctest, including the necessary displayhook
703 # Do a proper resetting of doctest, including the necessary displayhook
704 # monkeypatching
704 # monkeypatching
705 try:
705 try:
706 doctest_reload()
706 doctest_reload()
707 except ImportError:
707 except ImportError:
708 warn("doctest module does not exist.")
708 warn("doctest module does not exist.")
709
709
710 # Set user colors (don't do it in the constructor above so that it
710 # Set user colors (don't do it in the constructor above so that it
711 # doesn't crash if colors option is invalid)
711 # doesn't crash if colors option is invalid)
712 self.magic_colors(rc.colors)
712 self.magic_colors(rc.colors)
713
713
714 # Set calling of pdb on exceptions
714 # Set calling of pdb on exceptions
715 self.call_pdb = rc.pdb
715 self.call_pdb = rc.pdb
716
716
717 # Load user aliases
717 # Load user aliases
718 for alias in rc.alias:
718 for alias in rc.alias:
719 self.magic_alias(alias)
719 self.magic_alias(alias)
720
720
721 self.hooks.late_startup_hook()
721 self.hooks.late_startup_hook()
722
722
723 for cmd in self.rc.autoexec:
723 for cmd in self.rc.autoexec:
724 #print "autoexec>",cmd #dbg
724 #print "autoexec>",cmd #dbg
725 self.api.runlines(cmd)
725 self.api.runlines(cmd)
726
726
727 batchrun = False
727 batchrun = False
728 for batchfile in [path(arg) for arg in self.rc.args
728 for batchfile in [path(arg) for arg in self.rc.args
729 if arg.lower().endswith('.ipy')]:
729 if arg.lower().endswith('.ipy')]:
730 if not batchfile.isfile():
730 if not batchfile.isfile():
731 print "No such batch file:", batchfile
731 print "No such batch file:", batchfile
732 continue
732 continue
733 self.api.runlines(batchfile.text())
733 self.api.runlines(batchfile.text())
734 batchrun = True
734 batchrun = True
735 # without -i option, exit after running the batch file
735 # without -i option, exit after running the batch file
736 if batchrun and not self.rc.interact:
736 if batchrun and not self.rc.interact:
737 self.exit_now = True
737 self.exit_now = True
738
738
739 def add_builtins(self):
739 def add_builtins(self):
740 """Store ipython references into the builtin namespace.
740 """Store ipython references into the builtin namespace.
741
741
742 Some parts of ipython operate via builtins injected here, which hold a
742 Some parts of ipython operate via builtins injected here, which hold a
743 reference to IPython itself."""
743 reference to IPython itself."""
744
744
745 # TODO: deprecate all of these, they are unsafe
745 # TODO: deprecate all of these, they are unsafe
746 builtins_new = dict(__IPYTHON__ = self,
746 builtins_new = dict(__IPYTHON__ = self,
747 ip_set_hook = self.set_hook,
747 ip_set_hook = self.set_hook,
748 jobs = self.jobs,
748 jobs = self.jobs,
749 ipmagic = wrap_deprecated(self.ipmagic,'_ip.magic()'),
749 ipmagic = wrap_deprecated(self.ipmagic,'_ip.magic()'),
750 ipalias = wrap_deprecated(self.ipalias),
750 ipalias = wrap_deprecated(self.ipalias),
751 ipsystem = wrap_deprecated(self.ipsystem,'_ip.system()'),
751 ipsystem = wrap_deprecated(self.ipsystem,'_ip.system()'),
752 #_ip = self.api
752 #_ip = self.api
753 )
753 )
754 for biname,bival in builtins_new.items():
754 for biname,bival in builtins_new.items():
755 try:
755 try:
756 # store the orignal value so we can restore it
756 # store the orignal value so we can restore it
757 self.builtins_added[biname] = __builtin__.__dict__[biname]
757 self.builtins_added[biname] = __builtin__.__dict__[biname]
758 except KeyError:
758 except KeyError:
759 # or mark that it wasn't defined, and we'll just delete it at
759 # or mark that it wasn't defined, and we'll just delete it at
760 # cleanup
760 # cleanup
761 self.builtins_added[biname] = Undefined
761 self.builtins_added[biname] = Undefined
762 __builtin__.__dict__[biname] = bival
762 __builtin__.__dict__[biname] = bival
763
763
764 # Keep in the builtins a flag for when IPython is active. We set it
764 # Keep in the builtins a flag for when IPython is active. We set it
765 # with setdefault so that multiple nested IPythons don't clobber one
765 # with setdefault so that multiple nested IPythons don't clobber one
766 # another. Each will increase its value by one upon being activated,
766 # another. Each will increase its value by one upon being activated,
767 # which also gives us a way to determine the nesting level.
767 # which also gives us a way to determine the nesting level.
768 __builtin__.__dict__.setdefault('__IPYTHON__active',0)
768 __builtin__.__dict__.setdefault('__IPYTHON__active',0)
769
769
770 def clean_builtins(self):
770 def clean_builtins(self):
771 """Remove any builtins which might have been added by add_builtins, or
771 """Remove any builtins which might have been added by add_builtins, or
772 restore overwritten ones to their previous values."""
772 restore overwritten ones to their previous values."""
773 for biname,bival in self.builtins_added.items():
773 for biname,bival in self.builtins_added.items():
774 if bival is Undefined:
774 if bival is Undefined:
775 del __builtin__.__dict__[biname]
775 del __builtin__.__dict__[biname]
776 else:
776 else:
777 __builtin__.__dict__[biname] = bival
777 __builtin__.__dict__[biname] = bival
778 self.builtins_added.clear()
778 self.builtins_added.clear()
779
779
780 def set_hook(self,name,hook, priority = 50, str_key = None, re_key = None):
780 def set_hook(self,name,hook, priority = 50, str_key = None, re_key = None):
781 """set_hook(name,hook) -> sets an internal IPython hook.
781 """set_hook(name,hook) -> sets an internal IPython hook.
782
782
783 IPython exposes some of its internal API as user-modifiable hooks. By
783 IPython exposes some of its internal API as user-modifiable hooks. By
784 adding your function to one of these hooks, you can modify IPython's
784 adding your function to one of these hooks, you can modify IPython's
785 behavior to call at runtime your own routines."""
785 behavior to call at runtime your own routines."""
786
786
787 # At some point in the future, this should validate the hook before it
787 # At some point in the future, this should validate the hook before it
788 # accepts it. Probably at least check that the hook takes the number
788 # accepts it. Probably at least check that the hook takes the number
789 # of args it's supposed to.
789 # of args it's supposed to.
790
790
791 f = new.instancemethod(hook,self,self.__class__)
791 f = new.instancemethod(hook,self,self.__class__)
792
792
793 # check if the hook is for strdispatcher first
793 # check if the hook is for strdispatcher first
794 if str_key is not None:
794 if str_key is not None:
795 sdp = self.strdispatchers.get(name, StrDispatch())
795 sdp = self.strdispatchers.get(name, StrDispatch())
796 sdp.add_s(str_key, f, priority )
796 sdp.add_s(str_key, f, priority )
797 self.strdispatchers[name] = sdp
797 self.strdispatchers[name] = sdp
798 return
798 return
799 if re_key is not None:
799 if re_key is not None:
800 sdp = self.strdispatchers.get(name, StrDispatch())
800 sdp = self.strdispatchers.get(name, StrDispatch())
801 sdp.add_re(re.compile(re_key), f, priority )
801 sdp.add_re(re.compile(re_key), f, priority )
802 self.strdispatchers[name] = sdp
802 self.strdispatchers[name] = sdp
803 return
803 return
804
804
805 dp = getattr(self.hooks, name, None)
805 dp = getattr(self.hooks, name, None)
806 if name not in IPython.hooks.__all__:
806 if name not in IPython.hooks.__all__:
807 print "Warning! Hook '%s' is not one of %s" % (name, IPython.hooks.__all__ )
807 print "Warning! Hook '%s' is not one of %s" % (name, IPython.hooks.__all__ )
808 if not dp:
808 if not dp:
809 dp = IPython.hooks.CommandChainDispatcher()
809 dp = IPython.hooks.CommandChainDispatcher()
810
810
811 try:
811 try:
812 dp.add(f,priority)
812 dp.add(f,priority)
813 except AttributeError:
813 except AttributeError:
814 # it was not commandchain, plain old func - replace
814 # it was not commandchain, plain old func - replace
815 dp = f
815 dp = f
816
816
817 setattr(self.hooks,name, dp)
817 setattr(self.hooks,name, dp)
818
818
819
819
820 #setattr(self.hooks,name,new.instancemethod(hook,self,self.__class__))
820 #setattr(self.hooks,name,new.instancemethod(hook,self,self.__class__))
821
821
822 def set_crash_handler(self,crashHandler):
822 def set_crash_handler(self,crashHandler):
823 """Set the IPython crash handler.
823 """Set the IPython crash handler.
824
824
825 This must be a callable with a signature suitable for use as
825 This must be a callable with a signature suitable for use as
826 sys.excepthook."""
826 sys.excepthook."""
827
827
828 # Install the given crash handler as the Python exception hook
828 # Install the given crash handler as the Python exception hook
829 sys.excepthook = crashHandler
829 sys.excepthook = crashHandler
830
830
831 # The instance will store a pointer to this, so that runtime code
831 # The instance will store a pointer to this, so that runtime code
832 # (such as magics) can access it. This is because during the
832 # (such as magics) can access it. This is because during the
833 # read-eval loop, it gets temporarily overwritten (to deal with GUI
833 # read-eval loop, it gets temporarily overwritten (to deal with GUI
834 # frameworks).
834 # frameworks).
835 self.sys_excepthook = sys.excepthook
835 self.sys_excepthook = sys.excepthook
836
836
837
837
838 def set_custom_exc(self,exc_tuple,handler):
838 def set_custom_exc(self,exc_tuple,handler):
839 """set_custom_exc(exc_tuple,handler)
839 """set_custom_exc(exc_tuple,handler)
840
840
841 Set a custom exception handler, which will be called if any of the
841 Set a custom exception handler, which will be called if any of the
842 exceptions in exc_tuple occur in the mainloop (specifically, in the
842 exceptions in exc_tuple occur in the mainloop (specifically, in the
843 runcode() method.
843 runcode() method.
844
844
845 Inputs:
845 Inputs:
846
846
847 - exc_tuple: a *tuple* of valid exceptions to call the defined
847 - exc_tuple: a *tuple* of valid exceptions to call the defined
848 handler for. It is very important that you use a tuple, and NOT A
848 handler for. It is very important that you use a tuple, and NOT A
849 LIST here, because of the way Python's except statement works. If
849 LIST here, because of the way Python's except statement works. If
850 you only want to trap a single exception, use a singleton tuple:
850 you only want to trap a single exception, use a singleton tuple:
851
851
852 exc_tuple == (MyCustomException,)
852 exc_tuple == (MyCustomException,)
853
853
854 - handler: this must be defined as a function with the following
854 - handler: this must be defined as a function with the following
855 basic interface: def my_handler(self,etype,value,tb).
855 basic interface: def my_handler(self,etype,value,tb).
856
856
857 This will be made into an instance method (via new.instancemethod)
857 This will be made into an instance method (via new.instancemethod)
858 of IPython itself, and it will be called if any of the exceptions
858 of IPython itself, and it will be called if any of the exceptions
859 listed in the exc_tuple are caught. If the handler is None, an
859 listed in the exc_tuple are caught. If the handler is None, an
860 internal basic one is used, which just prints basic info.
860 internal basic one is used, which just prints basic info.
861
861
862 WARNING: by putting in your own exception handler into IPython's main
862 WARNING: by putting in your own exception handler into IPython's main
863 execution loop, you run a very good chance of nasty crashes. This
863 execution loop, you run a very good chance of nasty crashes. This
864 facility should only be used if you really know what you are doing."""
864 facility should only be used if you really know what you are doing."""
865
865
866 assert type(exc_tuple)==type(()) , \
866 assert type(exc_tuple)==type(()) , \
867 "The custom exceptions must be given AS A TUPLE."
867 "The custom exceptions must be given AS A TUPLE."
868
868
869 def dummy_handler(self,etype,value,tb):
869 def dummy_handler(self,etype,value,tb):
870 print '*** Simple custom exception handler ***'
870 print '*** Simple custom exception handler ***'
871 print 'Exception type :',etype
871 print 'Exception type :',etype
872 print 'Exception value:',value
872 print 'Exception value:',value
873 print 'Traceback :',tb
873 print 'Traceback :',tb
874 print 'Source code :','\n'.join(self.buffer)
874 print 'Source code :','\n'.join(self.buffer)
875
875
876 if handler is None: handler = dummy_handler
876 if handler is None: handler = dummy_handler
877
877
878 self.CustomTB = new.instancemethod(handler,self,self.__class__)
878 self.CustomTB = new.instancemethod(handler,self,self.__class__)
879 self.custom_exceptions = exc_tuple
879 self.custom_exceptions = exc_tuple
880
880
881 def set_custom_completer(self,completer,pos=0):
881 def set_custom_completer(self,completer,pos=0):
882 """set_custom_completer(completer,pos=0)
882 """set_custom_completer(completer,pos=0)
883
883
884 Adds a new custom completer function.
884 Adds a new custom completer function.
885
885
886 The position argument (defaults to 0) is the index in the completers
886 The position argument (defaults to 0) is the index in the completers
887 list where you want the completer to be inserted."""
887 list where you want the completer to be inserted."""
888
888
889 newcomp = new.instancemethod(completer,self.Completer,
889 newcomp = new.instancemethod(completer,self.Completer,
890 self.Completer.__class__)
890 self.Completer.__class__)
891 self.Completer.matchers.insert(pos,newcomp)
891 self.Completer.matchers.insert(pos,newcomp)
892
892
893 def set_completer(self):
893 def set_completer(self):
894 """reset readline's completer to be our own."""
894 """reset readline's completer to be our own."""
895 self.readline.set_completer(self.Completer.complete)
895 self.readline.set_completer(self.Completer.complete)
896
896
897 def _get_call_pdb(self):
897 def _get_call_pdb(self):
898 return self._call_pdb
898 return self._call_pdb
899
899
900 def _set_call_pdb(self,val):
900 def _set_call_pdb(self,val):
901
901
902 if val not in (0,1,False,True):
902 if val not in (0,1,False,True):
903 raise ValueError,'new call_pdb value must be boolean'
903 raise ValueError,'new call_pdb value must be boolean'
904
904
905 # store value in instance
905 # store value in instance
906 self._call_pdb = val
906 self._call_pdb = val
907
907
908 # notify the actual exception handlers
908 # notify the actual exception handlers
909 self.InteractiveTB.call_pdb = val
909 self.InteractiveTB.call_pdb = val
910 if self.isthreaded:
910 if self.isthreaded:
911 try:
911 try:
912 self.sys_excepthook.call_pdb = val
912 self.sys_excepthook.call_pdb = val
913 except:
913 except:
914 warn('Failed to activate pdb for threaded exception handler')
914 warn('Failed to activate pdb for threaded exception handler')
915
915
916 call_pdb = property(_get_call_pdb,_set_call_pdb,None,
916 call_pdb = property(_get_call_pdb,_set_call_pdb,None,
917 'Control auto-activation of pdb at exceptions')
917 'Control auto-activation of pdb at exceptions')
918
918
919
919
920 # These special functions get installed in the builtin namespace, to
920 # These special functions get installed in the builtin namespace, to
921 # provide programmatic (pure python) access to magics, aliases and system
921 # provide programmatic (pure python) access to magics, aliases and system
922 # calls. This is important for logging, user scripting, and more.
922 # calls. This is important for logging, user scripting, and more.
923
923
924 # We are basically exposing, via normal python functions, the three
924 # We are basically exposing, via normal python functions, the three
925 # mechanisms in which ipython offers special call modes (magics for
925 # mechanisms in which ipython offers special call modes (magics for
926 # internal control, aliases for direct system access via pre-selected
926 # internal control, aliases for direct system access via pre-selected
927 # names, and !cmd for calling arbitrary system commands).
927 # names, and !cmd for calling arbitrary system commands).
928
928
929 def ipmagic(self,arg_s):
929 def ipmagic(self,arg_s):
930 """Call a magic function by name.
930 """Call a magic function by name.
931
931
932 Input: a string containing the name of the magic function to call and any
932 Input: a string containing the name of the magic function to call and any
933 additional arguments to be passed to the magic.
933 additional arguments to be passed to the magic.
934
934
935 ipmagic('name -opt foo bar') is equivalent to typing at the ipython
935 ipmagic('name -opt foo bar') is equivalent to typing at the ipython
936 prompt:
936 prompt:
937
937
938 In[1]: %name -opt foo bar
938 In[1]: %name -opt foo bar
939
939
940 To call a magic without arguments, simply use ipmagic('name').
940 To call a magic without arguments, simply use ipmagic('name').
941
941
942 This provides a proper Python function to call IPython's magics in any
942 This provides a proper Python function to call IPython's magics in any
943 valid Python code you can type at the interpreter, including loops and
943 valid Python code you can type at the interpreter, including loops and
944 compound statements. It is added by IPython to the Python builtin
944 compound statements. It is added by IPython to the Python builtin
945 namespace upon initialization."""
945 namespace upon initialization."""
946
946
947 args = arg_s.split(' ',1)
947 args = arg_s.split(' ',1)
948 magic_name = args[0]
948 magic_name = args[0]
949 magic_name = magic_name.lstrip(self.ESC_MAGIC)
949 magic_name = magic_name.lstrip(self.ESC_MAGIC)
950
950
951 try:
951 try:
952 magic_args = args[1]
952 magic_args = args[1]
953 except IndexError:
953 except IndexError:
954 magic_args = ''
954 magic_args = ''
955 fn = getattr(self,'magic_'+magic_name,None)
955 fn = getattr(self,'magic_'+magic_name,None)
956 if fn is None:
956 if fn is None:
957 error("Magic function `%s` not found." % magic_name)
957 error("Magic function `%s` not found." % magic_name)
958 else:
958 else:
959 magic_args = self.var_expand(magic_args,1)
959 magic_args = self.var_expand(magic_args,1)
960 return fn(magic_args)
960 return fn(magic_args)
961
961
962 def ipalias(self,arg_s):
962 def ipalias(self,arg_s):
963 """Call an alias by name.
963 """Call an alias by name.
964
964
965 Input: a string containing the name of the alias to call and any
965 Input: a string containing the name of the alias to call and any
966 additional arguments to be passed to the magic.
966 additional arguments to be passed to the magic.
967
967
968 ipalias('name -opt foo bar') is equivalent to typing at the ipython
968 ipalias('name -opt foo bar') is equivalent to typing at the ipython
969 prompt:
969 prompt:
970
970
971 In[1]: name -opt foo bar
971 In[1]: name -opt foo bar
972
972
973 To call an alias without arguments, simply use ipalias('name').
973 To call an alias without arguments, simply use ipalias('name').
974
974
975 This provides a proper Python function to call IPython's aliases in any
975 This provides a proper Python function to call IPython's aliases in any
976 valid Python code you can type at the interpreter, including loops and
976 valid Python code you can type at the interpreter, including loops and
977 compound statements. It is added by IPython to the Python builtin
977 compound statements. It is added by IPython to the Python builtin
978 namespace upon initialization."""
978 namespace upon initialization."""
979
979
980 args = arg_s.split(' ',1)
980 args = arg_s.split(' ',1)
981 alias_name = args[0]
981 alias_name = args[0]
982 try:
982 try:
983 alias_args = args[1]
983 alias_args = args[1]
984 except IndexError:
984 except IndexError:
985 alias_args = ''
985 alias_args = ''
986 if alias_name in self.alias_table:
986 if alias_name in self.alias_table:
987 self.call_alias(alias_name,alias_args)
987 self.call_alias(alias_name,alias_args)
988 else:
988 else:
989 error("Alias `%s` not found." % alias_name)
989 error("Alias `%s` not found." % alias_name)
990
990
991 def ipsystem(self,arg_s):
991 def ipsystem(self,arg_s):
992 """Make a system call, using IPython."""
992 """Make a system call, using IPython."""
993
993
994 self.system(arg_s)
994 self.system(arg_s)
995
995
996 def complete(self,text):
996 def complete(self,text):
997 """Return a sorted list of all possible completions on text.
997 """Return a sorted list of all possible completions on text.
998
998
999 Inputs:
999 Inputs:
1000
1000
1001 - text: a string of text to be completed on.
1001 - text: a string of text to be completed on.
1002
1002
1003 This is a wrapper around the completion mechanism, similar to what
1003 This is a wrapper around the completion mechanism, similar to what
1004 readline does at the command line when the TAB key is hit. By
1004 readline does at the command line when the TAB key is hit. By
1005 exposing it as a method, it can be used by other non-readline
1005 exposing it as a method, it can be used by other non-readline
1006 environments (such as GUIs) for text completion.
1006 environments (such as GUIs) for text completion.
1007
1007
1008 Simple usage example:
1008 Simple usage example:
1009
1009
1010 In [1]: x = 'hello'
1010 In [7]: x = 'hello'
1011
1011
1012 In [2]: __IP.complete('x.l')
1012 In [8]: x
1013 Out[2]: ['x.ljust', 'x.lower', 'x.lstrip']"""
1013 Out[8]: 'hello'
1014
1015 In [9]: print x
1016 hello
1017
1018 In [10]: _ip.IP.complete('x.l')
1019 Out[10]: ['x.ljust', 'x.lower', 'x.lstrip']
1020 """
1014
1021
1015 complete = self.Completer.complete
1022 complete = self.Completer.complete
1016 state = 0
1023 state = 0
1017 # use a dict so we get unique keys, since ipyhton's multiple
1024 # use a dict so we get unique keys, since ipyhton's multiple
1018 # completers can return duplicates. When we make 2.4 a requirement,
1025 # completers can return duplicates. When we make 2.4 a requirement,
1019 # start using sets instead, which are faster.
1026 # start using sets instead, which are faster.
1020 comps = {}
1027 comps = {}
1021 while True:
1028 while True:
1022 newcomp = complete(text,state,line_buffer=text)
1029 newcomp = complete(text,state,line_buffer=text)
1023 if newcomp is None:
1030 if newcomp is None:
1024 break
1031 break
1025 comps[newcomp] = 1
1032 comps[newcomp] = 1
1026 state += 1
1033 state += 1
1027 outcomps = comps.keys()
1034 outcomps = comps.keys()
1028 outcomps.sort()
1035 outcomps.sort()
1036 print "T:",text,"OC:",outcomps # dbg
1037 #print "vars:",self.user_ns.keys()
1029 return outcomps
1038 return outcomps
1030
1039
1031 def set_completer_frame(self, frame=None):
1040 def set_completer_frame(self, frame=None):
1032 if frame:
1041 if frame:
1033 self.Completer.namespace = frame.f_locals
1042 self.Completer.namespace = frame.f_locals
1034 self.Completer.global_namespace = frame.f_globals
1043 self.Completer.global_namespace = frame.f_globals
1035 else:
1044 else:
1036 self.Completer.namespace = self.user_ns
1045 self.Completer.namespace = self.user_ns
1037 self.Completer.global_namespace = self.user_global_ns
1046 self.Completer.global_namespace = self.user_global_ns
1038
1047
1039 def init_auto_alias(self):
1048 def init_auto_alias(self):
1040 """Define some aliases automatically.
1049 """Define some aliases automatically.
1041
1050
1042 These are ALL parameter-less aliases"""
1051 These are ALL parameter-less aliases"""
1043
1052
1044 for alias,cmd in self.auto_alias:
1053 for alias,cmd in self.auto_alias:
1045 self.getapi().defalias(alias,cmd)
1054 self.getapi().defalias(alias,cmd)
1046
1055
1047
1056
1048 def alias_table_validate(self,verbose=0):
1057 def alias_table_validate(self,verbose=0):
1049 """Update information about the alias table.
1058 """Update information about the alias table.
1050
1059
1051 In particular, make sure no Python keywords/builtins are in it."""
1060 In particular, make sure no Python keywords/builtins are in it."""
1052
1061
1053 no_alias = self.no_alias
1062 no_alias = self.no_alias
1054 for k in self.alias_table.keys():
1063 for k in self.alias_table.keys():
1055 if k in no_alias:
1064 if k in no_alias:
1056 del self.alias_table[k]
1065 del self.alias_table[k]
1057 if verbose:
1066 if verbose:
1058 print ("Deleting alias <%s>, it's a Python "
1067 print ("Deleting alias <%s>, it's a Python "
1059 "keyword or builtin." % k)
1068 "keyword or builtin." % k)
1060
1069
1061 def set_autoindent(self,value=None):
1070 def set_autoindent(self,value=None):
1062 """Set the autoindent flag, checking for readline support.
1071 """Set the autoindent flag, checking for readline support.
1063
1072
1064 If called with no arguments, it acts as a toggle."""
1073 If called with no arguments, it acts as a toggle."""
1065
1074
1066 if not self.has_readline:
1075 if not self.has_readline:
1067 if os.name == 'posix':
1076 if os.name == 'posix':
1068 warn("The auto-indent feature requires the readline library")
1077 warn("The auto-indent feature requires the readline library")
1069 self.autoindent = 0
1078 self.autoindent = 0
1070 return
1079 return
1071 if value is None:
1080 if value is None:
1072 self.autoindent = not self.autoindent
1081 self.autoindent = not self.autoindent
1073 else:
1082 else:
1074 self.autoindent = value
1083 self.autoindent = value
1075
1084
1076 def rc_set_toggle(self,rc_field,value=None):
1085 def rc_set_toggle(self,rc_field,value=None):
1077 """Set or toggle a field in IPython's rc config. structure.
1086 """Set or toggle a field in IPython's rc config. structure.
1078
1087
1079 If called with no arguments, it acts as a toggle.
1088 If called with no arguments, it acts as a toggle.
1080
1089
1081 If called with a non-existent field, the resulting AttributeError
1090 If called with a non-existent field, the resulting AttributeError
1082 exception will propagate out."""
1091 exception will propagate out."""
1083
1092
1084 rc_val = getattr(self.rc,rc_field)
1093 rc_val = getattr(self.rc,rc_field)
1085 if value is None:
1094 if value is None:
1086 value = not rc_val
1095 value = not rc_val
1087 setattr(self.rc,rc_field,value)
1096 setattr(self.rc,rc_field,value)
1088
1097
1089 def user_setup(self,ipythondir,rc_suffix,mode='install'):
1098 def user_setup(self,ipythondir,rc_suffix,mode='install'):
1090 """Install the user configuration directory.
1099 """Install the user configuration directory.
1091
1100
1092 Can be called when running for the first time or to upgrade the user's
1101 Can be called when running for the first time or to upgrade the user's
1093 .ipython/ directory with the mode parameter. Valid modes are 'install'
1102 .ipython/ directory with the mode parameter. Valid modes are 'install'
1094 and 'upgrade'."""
1103 and 'upgrade'."""
1095
1104
1096 def wait():
1105 def wait():
1097 try:
1106 try:
1098 raw_input("Please press <RETURN> to start IPython.")
1107 raw_input("Please press <RETURN> to start IPython.")
1099 except EOFError:
1108 except EOFError:
1100 print >> Term.cout
1109 print >> Term.cout
1101 print '*'*70
1110 print '*'*70
1102
1111
1103 cwd = os.getcwd() # remember where we started
1112 cwd = os.getcwd() # remember where we started
1104 glb = glob.glob
1113 glb = glob.glob
1105 print '*'*70
1114 print '*'*70
1106 if mode == 'install':
1115 if mode == 'install':
1107 print \
1116 print \
1108 """Welcome to IPython. I will try to create a personal configuration directory
1117 """Welcome to IPython. I will try to create a personal configuration directory
1109 where you can customize many aspects of IPython's functionality in:\n"""
1118 where you can customize many aspects of IPython's functionality in:\n"""
1110 else:
1119 else:
1111 print 'I am going to upgrade your configuration in:'
1120 print 'I am going to upgrade your configuration in:'
1112
1121
1113 print ipythondir
1122 print ipythondir
1114
1123
1115 rcdirend = os.path.join('IPython','UserConfig')
1124 rcdirend = os.path.join('IPython','UserConfig')
1116 cfg = lambda d: os.path.join(d,rcdirend)
1125 cfg = lambda d: os.path.join(d,rcdirend)
1117 try:
1126 try:
1118 rcdir = filter(os.path.isdir,map(cfg,sys.path))[0]
1127 rcdir = filter(os.path.isdir,map(cfg,sys.path))[0]
1119 print "Initializing from configuration",rcdir
1128 print "Initializing from configuration",rcdir
1120 except IndexError:
1129 except IndexError:
1121 warning = """
1130 warning = """
1122 Installation error. IPython's directory was not found.
1131 Installation error. IPython's directory was not found.
1123
1132
1124 Check the following:
1133 Check the following:
1125
1134
1126 The ipython/IPython directory should be in a directory belonging to your
1135 The ipython/IPython directory should be in a directory belonging to your
1127 PYTHONPATH environment variable (that is, it should be in a directory
1136 PYTHONPATH environment variable (that is, it should be in a directory
1128 belonging to sys.path). You can copy it explicitly there or just link to it.
1137 belonging to sys.path). You can copy it explicitly there or just link to it.
1129
1138
1130 IPython will create a minimal default configuration for you.
1139 IPython will create a minimal default configuration for you.
1131
1140
1132 """
1141 """
1133 warn(warning)
1142 warn(warning)
1134 wait()
1143 wait()
1135
1144
1136 if sys.platform =='win32':
1145 if sys.platform =='win32':
1137 inif = 'ipythonrc.ini'
1146 inif = 'ipythonrc.ini'
1138 else:
1147 else:
1139 inif = 'ipythonrc'
1148 inif = 'ipythonrc'
1140 minimal_setup = {'ipy_user_conf.py' : 'import ipy_defaults', inif : '# intentionally left blank' }
1149 minimal_setup = {'ipy_user_conf.py' : 'import ipy_defaults', inif : '# intentionally left blank' }
1141 os.makedirs(ipythondir, mode = 0777)
1150 os.makedirs(ipythondir, mode = 0777)
1142 for f, cont in minimal_setup.items():
1151 for f, cont in minimal_setup.items():
1143 open(ipythondir + '/' + f,'w').write(cont)
1152 open(ipythondir + '/' + f,'w').write(cont)
1144
1153
1145 return
1154 return
1146
1155
1147 if mode == 'install':
1156 if mode == 'install':
1148 try:
1157 try:
1149 shutil.copytree(rcdir,ipythondir)
1158 shutil.copytree(rcdir,ipythondir)
1150 os.chdir(ipythondir)
1159 os.chdir(ipythondir)
1151 rc_files = glb("ipythonrc*")
1160 rc_files = glb("ipythonrc*")
1152 for rc_file in rc_files:
1161 for rc_file in rc_files:
1153 os.rename(rc_file,rc_file+rc_suffix)
1162 os.rename(rc_file,rc_file+rc_suffix)
1154 except:
1163 except:
1155 warning = """
1164 warning = """
1156
1165
1157 There was a problem with the installation:
1166 There was a problem with the installation:
1158 %s
1167 %s
1159 Try to correct it or contact the developers if you think it's a bug.
1168 Try to correct it or contact the developers if you think it's a bug.
1160 IPython will proceed with builtin defaults.""" % sys.exc_info()[1]
1169 IPython will proceed with builtin defaults.""" % sys.exc_info()[1]
1161 warn(warning)
1170 warn(warning)
1162 wait()
1171 wait()
1163 return
1172 return
1164
1173
1165 elif mode == 'upgrade':
1174 elif mode == 'upgrade':
1166 try:
1175 try:
1167 os.chdir(ipythondir)
1176 os.chdir(ipythondir)
1168 except:
1177 except:
1169 print """
1178 print """
1170 Can not upgrade: changing to directory %s failed. Details:
1179 Can not upgrade: changing to directory %s failed. Details:
1171 %s
1180 %s
1172 """ % (ipythondir,sys.exc_info()[1])
1181 """ % (ipythondir,sys.exc_info()[1])
1173 wait()
1182 wait()
1174 return
1183 return
1175 else:
1184 else:
1176 sources = glb(os.path.join(rcdir,'[A-Za-z]*'))
1185 sources = glb(os.path.join(rcdir,'[A-Za-z]*'))
1177 for new_full_path in sources:
1186 for new_full_path in sources:
1178 new_filename = os.path.basename(new_full_path)
1187 new_filename = os.path.basename(new_full_path)
1179 if new_filename.startswith('ipythonrc'):
1188 if new_filename.startswith('ipythonrc'):
1180 new_filename = new_filename + rc_suffix
1189 new_filename = new_filename + rc_suffix
1181 # The config directory should only contain files, skip any
1190 # The config directory should only contain files, skip any
1182 # directories which may be there (like CVS)
1191 # directories which may be there (like CVS)
1183 if os.path.isdir(new_full_path):
1192 if os.path.isdir(new_full_path):
1184 continue
1193 continue
1185 if os.path.exists(new_filename):
1194 if os.path.exists(new_filename):
1186 old_file = new_filename+'.old'
1195 old_file = new_filename+'.old'
1187 if os.path.exists(old_file):
1196 if os.path.exists(old_file):
1188 os.remove(old_file)
1197 os.remove(old_file)
1189 os.rename(new_filename,old_file)
1198 os.rename(new_filename,old_file)
1190 shutil.copy(new_full_path,new_filename)
1199 shutil.copy(new_full_path,new_filename)
1191 else:
1200 else:
1192 raise ValueError,'unrecognized mode for install:',`mode`
1201 raise ValueError,'unrecognized mode for install:',`mode`
1193
1202
1194 # Fix line-endings to those native to each platform in the config
1203 # Fix line-endings to those native to each platform in the config
1195 # directory.
1204 # directory.
1196 try:
1205 try:
1197 os.chdir(ipythondir)
1206 os.chdir(ipythondir)
1198 except:
1207 except:
1199 print """
1208 print """
1200 Problem: changing to directory %s failed.
1209 Problem: changing to directory %s failed.
1201 Details:
1210 Details:
1202 %s
1211 %s
1203
1212
1204 Some configuration files may have incorrect line endings. This should not
1213 Some configuration files may have incorrect line endings. This should not
1205 cause any problems during execution. """ % (ipythondir,sys.exc_info()[1])
1214 cause any problems during execution. """ % (ipythondir,sys.exc_info()[1])
1206 wait()
1215 wait()
1207 else:
1216 else:
1208 for fname in glb('ipythonrc*'):
1217 for fname in glb('ipythonrc*'):
1209 try:
1218 try:
1210 native_line_ends(fname,backup=0)
1219 native_line_ends(fname,backup=0)
1211 except IOError:
1220 except IOError:
1212 pass
1221 pass
1213
1222
1214 if mode == 'install':
1223 if mode == 'install':
1215 print """
1224 print """
1216 Successful installation!
1225 Successful installation!
1217
1226
1218 Please read the sections 'Initial Configuration' and 'Quick Tips' in the
1227 Please read the sections 'Initial Configuration' and 'Quick Tips' in the
1219 IPython manual (there are both HTML and PDF versions supplied with the
1228 IPython manual (there are both HTML and PDF versions supplied with the
1220 distribution) to make sure that your system environment is properly configured
1229 distribution) to make sure that your system environment is properly configured
1221 to take advantage of IPython's features.
1230 to take advantage of IPython's features.
1222
1231
1223 Important note: the configuration system has changed! The old system is
1232 Important note: the configuration system has changed! The old system is
1224 still in place, but its setting may be partly overridden by the settings in
1233 still in place, but its setting may be partly overridden by the settings in
1225 "~/.ipython/ipy_user_conf.py" config file. Please take a look at the file
1234 "~/.ipython/ipy_user_conf.py" config file. Please take a look at the file
1226 if some of the new settings bother you.
1235 if some of the new settings bother you.
1227
1236
1228 """
1237 """
1229 else:
1238 else:
1230 print """
1239 print """
1231 Successful upgrade!
1240 Successful upgrade!
1232
1241
1233 All files in your directory:
1242 All files in your directory:
1234 %(ipythondir)s
1243 %(ipythondir)s
1235 which would have been overwritten by the upgrade were backed up with a .old
1244 which would have been overwritten by the upgrade were backed up with a .old
1236 extension. If you had made particular customizations in those files you may
1245 extension. If you had made particular customizations in those files you may
1237 want to merge them back into the new files.""" % locals()
1246 want to merge them back into the new files.""" % locals()
1238 wait()
1247 wait()
1239 os.chdir(cwd)
1248 os.chdir(cwd)
1240 # end user_setup()
1249 # end user_setup()
1241
1250
1242 def atexit_operations(self):
1251 def atexit_operations(self):
1243 """This will be executed at the time of exit.
1252 """This will be executed at the time of exit.
1244
1253
1245 Saving of persistent data should be performed here. """
1254 Saving of persistent data should be performed here. """
1246
1255
1247 #print '*** IPython exit cleanup ***' # dbg
1256 #print '*** IPython exit cleanup ***' # dbg
1248 # input history
1257 # input history
1249 self.savehist()
1258 self.savehist()
1250
1259
1251 # Cleanup all tempfiles left around
1260 # Cleanup all tempfiles left around
1252 for tfile in self.tempfiles:
1261 for tfile in self.tempfiles:
1253 try:
1262 try:
1254 os.unlink(tfile)
1263 os.unlink(tfile)
1255 except OSError:
1264 except OSError:
1256 pass
1265 pass
1257
1266
1258 self.hooks.shutdown_hook()
1267 self.hooks.shutdown_hook()
1259
1268
1260 def savehist(self):
1269 def savehist(self):
1261 """Save input history to a file (via readline library)."""
1270 """Save input history to a file (via readline library)."""
1262
1271
1263 if not self.has_readline:
1272 if not self.has_readline:
1264 return
1273 return
1265
1274
1266 try:
1275 try:
1267 self.readline.write_history_file(self.histfile)
1276 self.readline.write_history_file(self.histfile)
1268 except:
1277 except:
1269 print 'Unable to save IPython command history to file: ' + \
1278 print 'Unable to save IPython command history to file: ' + \
1270 `self.histfile`
1279 `self.histfile`
1271
1280
1272 def reloadhist(self):
1281 def reloadhist(self):
1273 """Reload the input history from disk file."""
1282 """Reload the input history from disk file."""
1274
1283
1275 if self.has_readline:
1284 if self.has_readline:
1276 try:
1285 try:
1277 self.readline.clear_history()
1286 self.readline.clear_history()
1278 self.readline.read_history_file(self.shell.histfile)
1287 self.readline.read_history_file(self.shell.histfile)
1279 except AttributeError:
1288 except AttributeError:
1280 pass
1289 pass
1281
1290
1282
1291
1283 def history_saving_wrapper(self, func):
1292 def history_saving_wrapper(self, func):
1284 """ Wrap func for readline history saving
1293 """ Wrap func for readline history saving
1285
1294
1286 Convert func into callable that saves & restores
1295 Convert func into callable that saves & restores
1287 history around the call """
1296 history around the call """
1288
1297
1289 if not self.has_readline:
1298 if not self.has_readline:
1290 return func
1299 return func
1291
1300
1292 def wrapper():
1301 def wrapper():
1293 self.savehist()
1302 self.savehist()
1294 try:
1303 try:
1295 func()
1304 func()
1296 finally:
1305 finally:
1297 readline.read_history_file(self.histfile)
1306 readline.read_history_file(self.histfile)
1298 return wrapper
1307 return wrapper
1299
1308
1300
1309
1301 def pre_readline(self):
1310 def pre_readline(self):
1302 """readline hook to be used at the start of each line.
1311 """readline hook to be used at the start of each line.
1303
1312
1304 Currently it handles auto-indent only."""
1313 Currently it handles auto-indent only."""
1305
1314
1306 #debugx('self.indent_current_nsp','pre_readline:')
1315 #debugx('self.indent_current_nsp','pre_readline:')
1307
1316
1308 if self.rl_do_indent:
1317 if self.rl_do_indent:
1309 self.readline.insert_text(self.indent_current_str())
1318 self.readline.insert_text(self.indent_current_str())
1310 if self.rl_next_input is not None:
1319 if self.rl_next_input is not None:
1311 self.readline.insert_text(self.rl_next_input)
1320 self.readline.insert_text(self.rl_next_input)
1312 self.rl_next_input = None
1321 self.rl_next_input = None
1313
1322
1314 def init_readline(self):
1323 def init_readline(self):
1315 """Command history completion/saving/reloading."""
1324 """Command history completion/saving/reloading."""
1316
1325
1317
1326
1318 import IPython.rlineimpl as readline
1327 import IPython.rlineimpl as readline
1319
1328
1320 if not readline.have_readline:
1329 if not readline.have_readline:
1321 self.has_readline = 0
1330 self.has_readline = 0
1322 self.readline = None
1331 self.readline = None
1323 # no point in bugging windows users with this every time:
1332 # no point in bugging windows users with this every time:
1324 warn('Readline services not available on this platform.')
1333 warn('Readline services not available on this platform.')
1325 else:
1334 else:
1326 sys.modules['readline'] = readline
1335 sys.modules['readline'] = readline
1327 import atexit
1336 import atexit
1328 from IPython.completer import IPCompleter
1337 from IPython.completer import IPCompleter
1329 self.Completer = IPCompleter(self,
1338 self.Completer = IPCompleter(self,
1330 self.user_ns,
1339 self.user_ns,
1331 self.user_global_ns,
1340 self.user_global_ns,
1332 self.rc.readline_omit__names,
1341 self.rc.readline_omit__names,
1333 self.alias_table)
1342 self.alias_table)
1334 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
1343 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
1335 self.strdispatchers['complete_command'] = sdisp
1344 self.strdispatchers['complete_command'] = sdisp
1336 self.Completer.custom_completers = sdisp
1345 self.Completer.custom_completers = sdisp
1337 # Platform-specific configuration
1346 # Platform-specific configuration
1338 if os.name == 'nt':
1347 if os.name == 'nt':
1339 self.readline_startup_hook = readline.set_pre_input_hook
1348 self.readline_startup_hook = readline.set_pre_input_hook
1340 else:
1349 else:
1341 self.readline_startup_hook = readline.set_startup_hook
1350 self.readline_startup_hook = readline.set_startup_hook
1342
1351
1343 # Load user's initrc file (readline config)
1352 # Load user's initrc file (readline config)
1344 # Or if libedit is used, load editrc.
1353 # Or if libedit is used, load editrc.
1345 inputrc_name = os.environ.get('INPUTRC')
1354 inputrc_name = os.environ.get('INPUTRC')
1346 if inputrc_name is None:
1355 if inputrc_name is None:
1347 home_dir = get_home_dir()
1356 home_dir = get_home_dir()
1348 if home_dir is not None:
1357 if home_dir is not None:
1349 inputrc_name = '.inputrc'
1358 inputrc_name = '.inputrc'
1350 if readline.uses_libedit:
1359 if readline.uses_libedit:
1351 inputrc_name = '.editrc'
1360 inputrc_name = '.editrc'
1352 inputrc_name = os.path.join(home_dir, inputrc_name)
1361 inputrc_name = os.path.join(home_dir, inputrc_name)
1353 if os.path.isfile(inputrc_name):
1362 if os.path.isfile(inputrc_name):
1354 try:
1363 try:
1355 readline.read_init_file(inputrc_name)
1364 readline.read_init_file(inputrc_name)
1356 except:
1365 except:
1357 warn('Problems reading readline initialization file <%s>'
1366 warn('Problems reading readline initialization file <%s>'
1358 % inputrc_name)
1367 % inputrc_name)
1359
1368
1360 self.has_readline = 1
1369 self.has_readline = 1
1361 self.readline = readline
1370 self.readline = readline
1362 # save this in sys so embedded copies can restore it properly
1371 # save this in sys so embedded copies can restore it properly
1363 sys.ipcompleter = self.Completer.complete
1372 sys.ipcompleter = self.Completer.complete
1364 self.set_completer()
1373 self.set_completer()
1365
1374
1366 # Configure readline according to user's prefs
1375 # Configure readline according to user's prefs
1367 # This is only done if GNU readline is being used. If libedit
1376 # This is only done if GNU readline is being used. If libedit
1368 # is being used (as on Leopard) the readline config is
1377 # is being used (as on Leopard) the readline config is
1369 # not run as the syntax for libedit is different.
1378 # not run as the syntax for libedit is different.
1370 if not readline.uses_libedit:
1379 if not readline.uses_libedit:
1371 for rlcommand in self.rc.readline_parse_and_bind:
1380 for rlcommand in self.rc.readline_parse_and_bind:
1372 readline.parse_and_bind(rlcommand)
1381 readline.parse_and_bind(rlcommand)
1373
1382
1374 # remove some chars from the delimiters list
1383 # remove some chars from the delimiters list
1375 delims = readline.get_completer_delims()
1384 delims = readline.get_completer_delims()
1376 delims = delims.translate(string._idmap,
1385 delims = delims.translate(string._idmap,
1377 self.rc.readline_remove_delims)
1386 self.rc.readline_remove_delims)
1378 readline.set_completer_delims(delims)
1387 readline.set_completer_delims(delims)
1379 # otherwise we end up with a monster history after a while:
1388 # otherwise we end up with a monster history after a while:
1380 readline.set_history_length(1000)
1389 readline.set_history_length(1000)
1381 try:
1390 try:
1382 #print '*** Reading readline history' # dbg
1391 #print '*** Reading readline history' # dbg
1383 readline.read_history_file(self.histfile)
1392 readline.read_history_file(self.histfile)
1384 except IOError:
1393 except IOError:
1385 pass # It doesn't exist yet.
1394 pass # It doesn't exist yet.
1386
1395
1387 atexit.register(self.atexit_operations)
1396 atexit.register(self.atexit_operations)
1388 del atexit
1397 del atexit
1389
1398
1390 # Configure auto-indent for all platforms
1399 # Configure auto-indent for all platforms
1391 self.set_autoindent(self.rc.autoindent)
1400 self.set_autoindent(self.rc.autoindent)
1392
1401
1393 def ask_yes_no(self,prompt,default=True):
1402 def ask_yes_no(self,prompt,default=True):
1394 if self.rc.quiet:
1403 if self.rc.quiet:
1395 return True
1404 return True
1396 return ask_yes_no(prompt,default)
1405 return ask_yes_no(prompt,default)
1397
1406
1398 def _should_recompile(self,e):
1407 def _should_recompile(self,e):
1399 """Utility routine for edit_syntax_error"""
1408 """Utility routine for edit_syntax_error"""
1400
1409
1401 if e.filename in ('<ipython console>','<input>','<string>',
1410 if e.filename in ('<ipython console>','<input>','<string>',
1402 '<console>','<BackgroundJob compilation>',
1411 '<console>','<BackgroundJob compilation>',
1403 None):
1412 None):
1404
1413
1405 return False
1414 return False
1406 try:
1415 try:
1407 if (self.rc.autoedit_syntax and
1416 if (self.rc.autoedit_syntax and
1408 not self.ask_yes_no('Return to editor to correct syntax error? '
1417 not self.ask_yes_no('Return to editor to correct syntax error? '
1409 '[Y/n] ','y')):
1418 '[Y/n] ','y')):
1410 return False
1419 return False
1411 except EOFError:
1420 except EOFError:
1412 return False
1421 return False
1413
1422
1414 def int0(x):
1423 def int0(x):
1415 try:
1424 try:
1416 return int(x)
1425 return int(x)
1417 except TypeError:
1426 except TypeError:
1418 return 0
1427 return 0
1419 # always pass integer line and offset values to editor hook
1428 # always pass integer line and offset values to editor hook
1420 self.hooks.fix_error_editor(e.filename,
1429 self.hooks.fix_error_editor(e.filename,
1421 int0(e.lineno),int0(e.offset),e.msg)
1430 int0(e.lineno),int0(e.offset),e.msg)
1422 return True
1431 return True
1423
1432
1424 def edit_syntax_error(self):
1433 def edit_syntax_error(self):
1425 """The bottom half of the syntax error handler called in the main loop.
1434 """The bottom half of the syntax error handler called in the main loop.
1426
1435
1427 Loop until syntax error is fixed or user cancels.
1436 Loop until syntax error is fixed or user cancels.
1428 """
1437 """
1429
1438
1430 while self.SyntaxTB.last_syntax_error:
1439 while self.SyntaxTB.last_syntax_error:
1431 # copy and clear last_syntax_error
1440 # copy and clear last_syntax_error
1432 err = self.SyntaxTB.clear_err_state()
1441 err = self.SyntaxTB.clear_err_state()
1433 if not self._should_recompile(err):
1442 if not self._should_recompile(err):
1434 return
1443 return
1435 try:
1444 try:
1436 # may set last_syntax_error again if a SyntaxError is raised
1445 # may set last_syntax_error again if a SyntaxError is raised
1437 self.safe_execfile(err.filename,self.user_ns)
1446 self.safe_execfile(err.filename,self.user_ns)
1438 except:
1447 except:
1439 self.showtraceback()
1448 self.showtraceback()
1440 else:
1449 else:
1441 try:
1450 try:
1442 f = file(err.filename)
1451 f = file(err.filename)
1443 try:
1452 try:
1444 sys.displayhook(f.read())
1453 sys.displayhook(f.read())
1445 finally:
1454 finally:
1446 f.close()
1455 f.close()
1447 except:
1456 except:
1448 self.showtraceback()
1457 self.showtraceback()
1449
1458
1450 def showsyntaxerror(self, filename=None):
1459 def showsyntaxerror(self, filename=None):
1451 """Display the syntax error that just occurred.
1460 """Display the syntax error that just occurred.
1452
1461
1453 This doesn't display a stack trace because there isn't one.
1462 This doesn't display a stack trace because there isn't one.
1454
1463
1455 If a filename is given, it is stuffed in the exception instead
1464 If a filename is given, it is stuffed in the exception instead
1456 of what was there before (because Python's parser always uses
1465 of what was there before (because Python's parser always uses
1457 "<string>" when reading from a string).
1466 "<string>" when reading from a string).
1458 """
1467 """
1459 etype, value, last_traceback = sys.exc_info()
1468 etype, value, last_traceback = sys.exc_info()
1460
1469
1461 # See note about these variables in showtraceback() below
1470 # See note about these variables in showtraceback() below
1462 sys.last_type = etype
1471 sys.last_type = etype
1463 sys.last_value = value
1472 sys.last_value = value
1464 sys.last_traceback = last_traceback
1473 sys.last_traceback = last_traceback
1465
1474
1466 if filename and etype is SyntaxError:
1475 if filename and etype is SyntaxError:
1467 # Work hard to stuff the correct filename in the exception
1476 # Work hard to stuff the correct filename in the exception
1468 try:
1477 try:
1469 msg, (dummy_filename, lineno, offset, line) = value
1478 msg, (dummy_filename, lineno, offset, line) = value
1470 except:
1479 except:
1471 # Not the format we expect; leave it alone
1480 # Not the format we expect; leave it alone
1472 pass
1481 pass
1473 else:
1482 else:
1474 # Stuff in the right filename
1483 # Stuff in the right filename
1475 try:
1484 try:
1476 # Assume SyntaxError is a class exception
1485 # Assume SyntaxError is a class exception
1477 value = SyntaxError(msg, (filename, lineno, offset, line))
1486 value = SyntaxError(msg, (filename, lineno, offset, line))
1478 except:
1487 except:
1479 # If that failed, assume SyntaxError is a string
1488 # If that failed, assume SyntaxError is a string
1480 value = msg, (filename, lineno, offset, line)
1489 value = msg, (filename, lineno, offset, line)
1481 self.SyntaxTB(etype,value,[])
1490 self.SyntaxTB(etype,value,[])
1482
1491
1483 def debugger(self,force=False):
1492 def debugger(self,force=False):
1484 """Call the pydb/pdb debugger.
1493 """Call the pydb/pdb debugger.
1485
1494
1486 Keywords:
1495 Keywords:
1487
1496
1488 - force(False): by default, this routine checks the instance call_pdb
1497 - force(False): by default, this routine checks the instance call_pdb
1489 flag and does not actually invoke the debugger if the flag is false.
1498 flag and does not actually invoke the debugger if the flag is false.
1490 The 'force' option forces the debugger to activate even if the flag
1499 The 'force' option forces the debugger to activate even if the flag
1491 is false.
1500 is false.
1492 """
1501 """
1493
1502
1494 if not (force or self.call_pdb):
1503 if not (force or self.call_pdb):
1495 return
1504 return
1496
1505
1497 if not hasattr(sys,'last_traceback'):
1506 if not hasattr(sys,'last_traceback'):
1498 error('No traceback has been produced, nothing to debug.')
1507 error('No traceback has been produced, nothing to debug.')
1499 return
1508 return
1500
1509
1501 # use pydb if available
1510 # use pydb if available
1502 if Debugger.has_pydb:
1511 if Debugger.has_pydb:
1503 from pydb import pm
1512 from pydb import pm
1504 else:
1513 else:
1505 # fallback to our internal debugger
1514 # fallback to our internal debugger
1506 pm = lambda : self.InteractiveTB.debugger(force=True)
1515 pm = lambda : self.InteractiveTB.debugger(force=True)
1507 self.history_saving_wrapper(pm)()
1516 self.history_saving_wrapper(pm)()
1508
1517
1509 def showtraceback(self,exc_tuple = None,filename=None,tb_offset=None):
1518 def showtraceback(self,exc_tuple = None,filename=None,tb_offset=None):
1510 """Display the exception that just occurred.
1519 """Display the exception that just occurred.
1511
1520
1512 If nothing is known about the exception, this is the method which
1521 If nothing is known about the exception, this is the method which
1513 should be used throughout the code for presenting user tracebacks,
1522 should be used throughout the code for presenting user tracebacks,
1514 rather than directly invoking the InteractiveTB object.
1523 rather than directly invoking the InteractiveTB object.
1515
1524
1516 A specific showsyntaxerror() also exists, but this method can take
1525 A specific showsyntaxerror() also exists, but this method can take
1517 care of calling it if needed, so unless you are explicitly catching a
1526 care of calling it if needed, so unless you are explicitly catching a
1518 SyntaxError exception, don't try to analyze the stack manually and
1527 SyntaxError exception, don't try to analyze the stack manually and
1519 simply call this method."""
1528 simply call this method."""
1520
1529
1521
1530
1522 # Though this won't be called by syntax errors in the input line,
1531 # Though this won't be called by syntax errors in the input line,
1523 # there may be SyntaxError cases whith imported code.
1532 # there may be SyntaxError cases whith imported code.
1524
1533
1525 try:
1534 try:
1526 if exc_tuple is None:
1535 if exc_tuple is None:
1527 etype, value, tb = sys.exc_info()
1536 etype, value, tb = sys.exc_info()
1528 else:
1537 else:
1529 etype, value, tb = exc_tuple
1538 etype, value, tb = exc_tuple
1530
1539
1531 if etype is SyntaxError:
1540 if etype is SyntaxError:
1532 self.showsyntaxerror(filename)
1541 self.showsyntaxerror(filename)
1533 elif etype is IPython.ipapi.UsageError:
1542 elif etype is IPython.ipapi.UsageError:
1534 print "UsageError:", value
1543 print "UsageError:", value
1535 else:
1544 else:
1536 # WARNING: these variables are somewhat deprecated and not
1545 # WARNING: these variables are somewhat deprecated and not
1537 # necessarily safe to use in a threaded environment, but tools
1546 # necessarily safe to use in a threaded environment, but tools
1538 # like pdb depend on their existence, so let's set them. If we
1547 # like pdb depend on their existence, so let's set them. If we
1539 # find problems in the field, we'll need to revisit their use.
1548 # find problems in the field, we'll need to revisit their use.
1540 sys.last_type = etype
1549 sys.last_type = etype
1541 sys.last_value = value
1550 sys.last_value = value
1542 sys.last_traceback = tb
1551 sys.last_traceback = tb
1543
1552
1544 if etype in self.custom_exceptions:
1553 if etype in self.custom_exceptions:
1545 self.CustomTB(etype,value,tb)
1554 self.CustomTB(etype,value,tb)
1546 else:
1555 else:
1547 self.InteractiveTB(etype,value,tb,tb_offset=tb_offset)
1556 self.InteractiveTB(etype,value,tb,tb_offset=tb_offset)
1548 if self.InteractiveTB.call_pdb and self.has_readline:
1557 if self.InteractiveTB.call_pdb and self.has_readline:
1549 # pdb mucks up readline, fix it back
1558 # pdb mucks up readline, fix it back
1550 self.set_completer()
1559 self.set_completer()
1551 except KeyboardInterrupt:
1560 except KeyboardInterrupt:
1552 self.write("\nKeyboardInterrupt\n")
1561 self.write("\nKeyboardInterrupt\n")
1553
1562
1554
1563
1555
1564
1556 def mainloop(self,banner=None):
1565 def mainloop(self,banner=None):
1557 """Creates the local namespace and starts the mainloop.
1566 """Creates the local namespace and starts the mainloop.
1558
1567
1559 If an optional banner argument is given, it will override the
1568 If an optional banner argument is given, it will override the
1560 internally created default banner."""
1569 internally created default banner."""
1561
1570
1562 if self.rc.c: # Emulate Python's -c option
1571 if self.rc.c: # Emulate Python's -c option
1563 self.exec_init_cmd()
1572 self.exec_init_cmd()
1564 if banner is None:
1573 if banner is None:
1565 if not self.rc.banner:
1574 if not self.rc.banner:
1566 banner = ''
1575 banner = ''
1567 # banner is string? Use it directly!
1576 # banner is string? Use it directly!
1568 elif isinstance(self.rc.banner,basestring):
1577 elif isinstance(self.rc.banner,basestring):
1569 banner = self.rc.banner
1578 banner = self.rc.banner
1570 else:
1579 else:
1571 banner = self.BANNER+self.banner2
1580 banner = self.BANNER+self.banner2
1572
1581
1573 while 1:
1582 while 1:
1574 try:
1583 try:
1575 self.interact(banner)
1584 self.interact(banner)
1576 #self.interact_with_readline()
1585 #self.interact_with_readline()
1577 # XXX for testing of a readline-decoupled repl loop, call interact_with_readline above
1586 # XXX for testing of a readline-decoupled repl loop, call interact_with_readline above
1578
1587
1579 break
1588 break
1580 except KeyboardInterrupt:
1589 except KeyboardInterrupt:
1581 # this should not be necessary, but KeyboardInterrupt
1590 # this should not be necessary, but KeyboardInterrupt
1582 # handling seems rather unpredictable...
1591 # handling seems rather unpredictable...
1583 self.write("\nKeyboardInterrupt in interact()\n")
1592 self.write("\nKeyboardInterrupt in interact()\n")
1584
1593
1585 def exec_init_cmd(self):
1594 def exec_init_cmd(self):
1586 """Execute a command given at the command line.
1595 """Execute a command given at the command line.
1587
1596
1588 This emulates Python's -c option."""
1597 This emulates Python's -c option."""
1589
1598
1590 #sys.argv = ['-c']
1599 #sys.argv = ['-c']
1591 self.push(self.prefilter(self.rc.c, False))
1600 self.push(self.prefilter(self.rc.c, False))
1592 if not self.rc.interact:
1601 if not self.rc.interact:
1593 self.exit_now = True
1602 self.exit_now = True
1594
1603
1595 def embed_mainloop(self,header='',local_ns=None,global_ns=None,stack_depth=0):
1604 def embed_mainloop(self,header='',local_ns=None,global_ns=None,stack_depth=0):
1596 """Embeds IPython into a running python program.
1605 """Embeds IPython into a running python program.
1597
1606
1598 Input:
1607 Input:
1599
1608
1600 - header: An optional header message can be specified.
1609 - header: An optional header message can be specified.
1601
1610
1602 - local_ns, global_ns: working namespaces. If given as None, the
1611 - local_ns, global_ns: working namespaces. If given as None, the
1603 IPython-initialized one is updated with __main__.__dict__, so that
1612 IPython-initialized one is updated with __main__.__dict__, so that
1604 program variables become visible but user-specific configuration
1613 program variables become visible but user-specific configuration
1605 remains possible.
1614 remains possible.
1606
1615
1607 - stack_depth: specifies how many levels in the stack to go to
1616 - stack_depth: specifies how many levels in the stack to go to
1608 looking for namespaces (when local_ns and global_ns are None). This
1617 looking for namespaces (when local_ns and global_ns are None). This
1609 allows an intermediate caller to make sure that this function gets
1618 allows an intermediate caller to make sure that this function gets
1610 the namespace from the intended level in the stack. By default (0)
1619 the namespace from the intended level in the stack. By default (0)
1611 it will get its locals and globals from the immediate caller.
1620 it will get its locals and globals from the immediate caller.
1612
1621
1613 Warning: it's possible to use this in a program which is being run by
1622 Warning: it's possible to use this in a program which is being run by
1614 IPython itself (via %run), but some funny things will happen (a few
1623 IPython itself (via %run), but some funny things will happen (a few
1615 globals get overwritten). In the future this will be cleaned up, as
1624 globals get overwritten). In the future this will be cleaned up, as
1616 there is no fundamental reason why it can't work perfectly."""
1625 there is no fundamental reason why it can't work perfectly."""
1617
1626
1618 # Get locals and globals from caller
1627 # Get locals and globals from caller
1619 if local_ns is None or global_ns is None:
1628 if local_ns is None or global_ns is None:
1620 call_frame = sys._getframe(stack_depth).f_back
1629 call_frame = sys._getframe(stack_depth).f_back
1621
1630
1622 if local_ns is None:
1631 if local_ns is None:
1623 local_ns = call_frame.f_locals
1632 local_ns = call_frame.f_locals
1624 if global_ns is None:
1633 if global_ns is None:
1625 global_ns = call_frame.f_globals
1634 global_ns = call_frame.f_globals
1626
1635
1627 # Update namespaces and fire up interpreter
1636 # Update namespaces and fire up interpreter
1628
1637
1629 # The global one is easy, we can just throw it in
1638 # The global one is easy, we can just throw it in
1630 self.user_global_ns = global_ns
1639 self.user_global_ns = global_ns
1631
1640
1632 # but the user/local one is tricky: ipython needs it to store internal
1641 # but the user/local one is tricky: ipython needs it to store internal
1633 # data, but we also need the locals. We'll copy locals in the user
1642 # data, but we also need the locals. We'll copy locals in the user
1634 # one, but will track what got copied so we can delete them at exit.
1643 # one, but will track what got copied so we can delete them at exit.
1635 # This is so that a later embedded call doesn't see locals from a
1644 # This is so that a later embedded call doesn't see locals from a
1636 # previous call (which most likely existed in a separate scope).
1645 # previous call (which most likely existed in a separate scope).
1637 local_varnames = local_ns.keys()
1646 local_varnames = local_ns.keys()
1638 self.user_ns.update(local_ns)
1647 self.user_ns.update(local_ns)
1648 #self.user_ns['local_ns'] = local_ns # dbg
1639
1649
1640 # Patch for global embedding to make sure that things don't overwrite
1650 # Patch for global embedding to make sure that things don't overwrite
1641 # user globals accidentally. Thanks to Richard <rxe@renre-europe.com>
1651 # user globals accidentally. Thanks to Richard <rxe@renre-europe.com>
1642 # FIXME. Test this a bit more carefully (the if.. is new)
1652 # FIXME. Test this a bit more carefully (the if.. is new)
1643 if local_ns is None and global_ns is None:
1653 if local_ns is None and global_ns is None:
1644 self.user_global_ns.update(__main__.__dict__)
1654 self.user_global_ns.update(__main__.__dict__)
1645
1655
1646 # make sure the tab-completer has the correct frame information, so it
1656 # make sure the tab-completer has the correct frame information, so it
1647 # actually completes using the frame's locals/globals
1657 # actually completes using the frame's locals/globals
1648 self.set_completer_frame()
1658 self.set_completer_frame()
1649
1659
1650 # before activating the interactive mode, we need to make sure that
1660 # before activating the interactive mode, we need to make sure that
1651 # all names in the builtin namespace needed by ipython point to
1661 # all names in the builtin namespace needed by ipython point to
1652 # ourselves, and not to other instances.
1662 # ourselves, and not to other instances.
1653 self.add_builtins()
1663 self.add_builtins()
1654
1664
1655 self.interact(header)
1665 self.interact(header)
1656
1666
1657 # now, purge out the user namespace from anything we might have added
1667 # now, purge out the user namespace from anything we might have added
1658 # from the caller's local namespace
1668 # from the caller's local namespace
1659 delvar = self.user_ns.pop
1669 delvar = self.user_ns.pop
1660 for var in local_varnames:
1670 for var in local_varnames:
1661 delvar(var,None)
1671 delvar(var,None)
1662 # and clean builtins we may have overridden
1672 # and clean builtins we may have overridden
1663 self.clean_builtins()
1673 self.clean_builtins()
1664
1674
1665 def interact_prompt(self):
1675 def interact_prompt(self):
1666 """ Print the prompt (in read-eval-print loop)
1676 """ Print the prompt (in read-eval-print loop)
1667
1677
1668 Provided for those who want to implement their own read-eval-print loop (e.g. GUIs), not
1678 Provided for those who want to implement their own read-eval-print loop (e.g. GUIs), not
1669 used in standard IPython flow.
1679 used in standard IPython flow.
1670 """
1680 """
1671 if self.more:
1681 if self.more:
1672 try:
1682 try:
1673 prompt = self.hooks.generate_prompt(True)
1683 prompt = self.hooks.generate_prompt(True)
1674 except:
1684 except:
1675 self.showtraceback()
1685 self.showtraceback()
1676 if self.autoindent:
1686 if self.autoindent:
1677 self.rl_do_indent = True
1687 self.rl_do_indent = True
1678
1688
1679 else:
1689 else:
1680 try:
1690 try:
1681 prompt = self.hooks.generate_prompt(False)
1691 prompt = self.hooks.generate_prompt(False)
1682 except:
1692 except:
1683 self.showtraceback()
1693 self.showtraceback()
1684 self.write(prompt)
1694 self.write(prompt)
1685
1695
1686 def interact_handle_input(self,line):
1696 def interact_handle_input(self,line):
1687 """ Handle the input line (in read-eval-print loop)
1697 """ Handle the input line (in read-eval-print loop)
1688
1698
1689 Provided for those who want to implement their own read-eval-print loop (e.g. GUIs), not
1699 Provided for those who want to implement their own read-eval-print loop (e.g. GUIs), not
1690 used in standard IPython flow.
1700 used in standard IPython flow.
1691 """
1701 """
1692 if line.lstrip() == line:
1702 if line.lstrip() == line:
1693 self.shadowhist.add(line.strip())
1703 self.shadowhist.add(line.strip())
1694 lineout = self.prefilter(line,self.more)
1704 lineout = self.prefilter(line,self.more)
1695
1705
1696 if line.strip():
1706 if line.strip():
1697 if self.more:
1707 if self.more:
1698 self.input_hist_raw[-1] += '%s\n' % line
1708 self.input_hist_raw[-1] += '%s\n' % line
1699 else:
1709 else:
1700 self.input_hist_raw.append('%s\n' % line)
1710 self.input_hist_raw.append('%s\n' % line)
1701
1711
1702
1712
1703 self.more = self.push(lineout)
1713 self.more = self.push(lineout)
1704 if (self.SyntaxTB.last_syntax_error and
1714 if (self.SyntaxTB.last_syntax_error and
1705 self.rc.autoedit_syntax):
1715 self.rc.autoedit_syntax):
1706 self.edit_syntax_error()
1716 self.edit_syntax_error()
1707
1717
1708 def interact_with_readline(self):
1718 def interact_with_readline(self):
1709 """ Demo of using interact_handle_input, interact_prompt
1719 """ Demo of using interact_handle_input, interact_prompt
1710
1720
1711 This is the main read-eval-print loop. If you need to implement your own (e.g. for GUI),
1721 This is the main read-eval-print loop. If you need to implement your own (e.g. for GUI),
1712 it should work like this.
1722 it should work like this.
1713 """
1723 """
1714 self.readline_startup_hook(self.pre_readline)
1724 self.readline_startup_hook(self.pre_readline)
1715 while not self.exit_now:
1725 while not self.exit_now:
1716 self.interact_prompt()
1726 self.interact_prompt()
1717 if self.more:
1727 if self.more:
1718 self.rl_do_indent = True
1728 self.rl_do_indent = True
1719 else:
1729 else:
1720 self.rl_do_indent = False
1730 self.rl_do_indent = False
1721 line = raw_input_original().decode(self.stdin_encoding)
1731 line = raw_input_original().decode(self.stdin_encoding)
1722 self.interact_handle_input(line)
1732 self.interact_handle_input(line)
1723
1733
1724
1734
1725 def interact(self, banner=None):
1735 def interact(self, banner=None):
1726 """Closely emulate the interactive Python console.
1736 """Closely emulate the interactive Python console.
1727
1737
1728 The optional banner argument specify the banner to print
1738 The optional banner argument specify the banner to print
1729 before the first interaction; by default it prints a banner
1739 before the first interaction; by default it prints a banner
1730 similar to the one printed by the real Python interpreter,
1740 similar to the one printed by the real Python interpreter,
1731 followed by the current class name in parentheses (so as not
1741 followed by the current class name in parentheses (so as not
1732 to confuse this with the real interpreter -- since it's so
1742 to confuse this with the real interpreter -- since it's so
1733 close!).
1743 close!).
1734
1744
1735 """
1745 """
1736
1746
1737 if self.exit_now:
1747 if self.exit_now:
1738 # batch run -> do not interact
1748 # batch run -> do not interact
1739 return
1749 return
1740 cprt = 'Type "copyright", "credits" or "license" for more information.'
1750 cprt = 'Type "copyright", "credits" or "license" for more information.'
1741 if banner is None:
1751 if banner is None:
1742 self.write("Python %s on %s\n%s\n(%s)\n" %
1752 self.write("Python %s on %s\n%s\n(%s)\n" %
1743 (sys.version, sys.platform, cprt,
1753 (sys.version, sys.platform, cprt,
1744 self.__class__.__name__))
1754 self.__class__.__name__))
1745 else:
1755 else:
1746 self.write(banner)
1756 self.write(banner)
1747
1757
1748 more = 0
1758 more = 0
1749
1759
1750 # Mark activity in the builtins
1760 # Mark activity in the builtins
1751 __builtin__.__dict__['__IPYTHON__active'] += 1
1761 __builtin__.__dict__['__IPYTHON__active'] += 1
1752
1762
1753 if self.has_readline:
1763 if self.has_readline:
1754 self.readline_startup_hook(self.pre_readline)
1764 self.readline_startup_hook(self.pre_readline)
1755 # exit_now is set by a call to %Exit or %Quit
1765 # exit_now is set by a call to %Exit or %Quit
1756
1766
1757 while not self.exit_now:
1767 while not self.exit_now:
1758 self.hooks.pre_prompt_hook()
1768 self.hooks.pre_prompt_hook()
1759 if more:
1769 if more:
1760 try:
1770 try:
1761 prompt = self.hooks.generate_prompt(True)
1771 prompt = self.hooks.generate_prompt(True)
1762 except:
1772 except:
1763 self.showtraceback()
1773 self.showtraceback()
1764 if self.autoindent:
1774 if self.autoindent:
1765 self.rl_do_indent = True
1775 self.rl_do_indent = True
1766
1776
1767 else:
1777 else:
1768 try:
1778 try:
1769 prompt = self.hooks.generate_prompt(False)
1779 prompt = self.hooks.generate_prompt(False)
1770 except:
1780 except:
1771 self.showtraceback()
1781 self.showtraceback()
1772 try:
1782 try:
1773 line = self.raw_input(prompt,more)
1783 line = self.raw_input(prompt,more)
1774 if self.exit_now:
1784 if self.exit_now:
1775 # quick exit on sys.std[in|out] close
1785 # quick exit on sys.std[in|out] close
1776 break
1786 break
1777 if self.autoindent:
1787 if self.autoindent:
1778 self.rl_do_indent = False
1788 self.rl_do_indent = False
1779
1789
1780 except KeyboardInterrupt:
1790 except KeyboardInterrupt:
1781 #double-guard against keyboardinterrupts during kbdint handling
1791 #double-guard against keyboardinterrupts during kbdint handling
1782 try:
1792 try:
1783 self.write('\nKeyboardInterrupt\n')
1793 self.write('\nKeyboardInterrupt\n')
1784 self.resetbuffer()
1794 self.resetbuffer()
1785 # keep cache in sync with the prompt counter:
1795 # keep cache in sync with the prompt counter:
1786 self.outputcache.prompt_count -= 1
1796 self.outputcache.prompt_count -= 1
1787
1797
1788 if self.autoindent:
1798 if self.autoindent:
1789 self.indent_current_nsp = 0
1799 self.indent_current_nsp = 0
1790 more = 0
1800 more = 0
1791 except KeyboardInterrupt:
1801 except KeyboardInterrupt:
1792 pass
1802 pass
1793 except EOFError:
1803 except EOFError:
1794 if self.autoindent:
1804 if self.autoindent:
1795 self.rl_do_indent = False
1805 self.rl_do_indent = False
1796 self.readline_startup_hook(None)
1806 self.readline_startup_hook(None)
1797 self.write('\n')
1807 self.write('\n')
1798 self.exit()
1808 self.exit()
1799 except bdb.BdbQuit:
1809 except bdb.BdbQuit:
1800 warn('The Python debugger has exited with a BdbQuit exception.\n'
1810 warn('The Python debugger has exited with a BdbQuit exception.\n'
1801 'Because of how pdb handles the stack, it is impossible\n'
1811 'Because of how pdb handles the stack, it is impossible\n'
1802 'for IPython to properly format this particular exception.\n'
1812 'for IPython to properly format this particular exception.\n'
1803 'IPython will resume normal operation.')
1813 'IPython will resume normal operation.')
1804 except:
1814 except:
1805 # exceptions here are VERY RARE, but they can be triggered
1815 # exceptions here are VERY RARE, but they can be triggered
1806 # asynchronously by signal handlers, for example.
1816 # asynchronously by signal handlers, for example.
1807 self.showtraceback()
1817 self.showtraceback()
1808 else:
1818 else:
1809 more = self.push(line)
1819 more = self.push(line)
1810 if (self.SyntaxTB.last_syntax_error and
1820 if (self.SyntaxTB.last_syntax_error and
1811 self.rc.autoedit_syntax):
1821 self.rc.autoedit_syntax):
1812 self.edit_syntax_error()
1822 self.edit_syntax_error()
1813
1823
1814 # We are off again...
1824 # We are off again...
1815 __builtin__.__dict__['__IPYTHON__active'] -= 1
1825 __builtin__.__dict__['__IPYTHON__active'] -= 1
1816
1826
1817 def excepthook(self, etype, value, tb):
1827 def excepthook(self, etype, value, tb):
1818 """One more defense for GUI apps that call sys.excepthook.
1828 """One more defense for GUI apps that call sys.excepthook.
1819
1829
1820 GUI frameworks like wxPython trap exceptions and call
1830 GUI frameworks like wxPython trap exceptions and call
1821 sys.excepthook themselves. I guess this is a feature that
1831 sys.excepthook themselves. I guess this is a feature that
1822 enables them to keep running after exceptions that would
1832 enables them to keep running after exceptions that would
1823 otherwise kill their mainloop. This is a bother for IPython
1833 otherwise kill their mainloop. This is a bother for IPython
1824 which excepts to catch all of the program exceptions with a try:
1834 which excepts to catch all of the program exceptions with a try:
1825 except: statement.
1835 except: statement.
1826
1836
1827 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
1837 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
1828 any app directly invokes sys.excepthook, it will look to the user like
1838 any app directly invokes sys.excepthook, it will look to the user like
1829 IPython crashed. In order to work around this, we can disable the
1839 IPython crashed. In order to work around this, we can disable the
1830 CrashHandler and replace it with this excepthook instead, which prints a
1840 CrashHandler and replace it with this excepthook instead, which prints a
1831 regular traceback using our InteractiveTB. In this fashion, apps which
1841 regular traceback using our InteractiveTB. In this fashion, apps which
1832 call sys.excepthook will generate a regular-looking exception from
1842 call sys.excepthook will generate a regular-looking exception from
1833 IPython, and the CrashHandler will only be triggered by real IPython
1843 IPython, and the CrashHandler will only be triggered by real IPython
1834 crashes.
1844 crashes.
1835
1845
1836 This hook should be used sparingly, only in places which are not likely
1846 This hook should be used sparingly, only in places which are not likely
1837 to be true IPython errors.
1847 to be true IPython errors.
1838 """
1848 """
1839 self.showtraceback((etype,value,tb),tb_offset=0)
1849 self.showtraceback((etype,value,tb),tb_offset=0)
1840
1850
1841 def expand_aliases(self,fn,rest):
1851 def expand_aliases(self,fn,rest):
1842 """ Expand multiple levels of aliases:
1852 """ Expand multiple levels of aliases:
1843
1853
1844 if:
1854 if:
1845
1855
1846 alias foo bar /tmp
1856 alias foo bar /tmp
1847 alias baz foo
1857 alias baz foo
1848
1858
1849 then:
1859 then:
1850
1860
1851 baz huhhahhei -> bar /tmp huhhahhei
1861 baz huhhahhei -> bar /tmp huhhahhei
1852
1862
1853 """
1863 """
1854 line = fn + " " + rest
1864 line = fn + " " + rest
1855
1865
1856 done = Set()
1866 done = Set()
1857 while 1:
1867 while 1:
1858 pre,fn,rest = prefilter.splitUserInput(line,
1868 pre,fn,rest = prefilter.splitUserInput(line,
1859 prefilter.shell_line_split)
1869 prefilter.shell_line_split)
1860 if fn in self.alias_table:
1870 if fn in self.alias_table:
1861 if fn in done:
1871 if fn in done:
1862 warn("Cyclic alias definition, repeated '%s'" % fn)
1872 warn("Cyclic alias definition, repeated '%s'" % fn)
1863 return ""
1873 return ""
1864 done.add(fn)
1874 done.add(fn)
1865
1875
1866 l2 = self.transform_alias(fn,rest)
1876 l2 = self.transform_alias(fn,rest)
1867 # dir -> dir
1877 # dir -> dir
1868 # print "alias",line, "->",l2 #dbg
1878 # print "alias",line, "->",l2 #dbg
1869 if l2 == line:
1879 if l2 == line:
1870 break
1880 break
1871 # ls -> ls -F should not recurse forever
1881 # ls -> ls -F should not recurse forever
1872 if l2.split(None,1)[0] == line.split(None,1)[0]:
1882 if l2.split(None,1)[0] == line.split(None,1)[0]:
1873 line = l2
1883 line = l2
1874 break
1884 break
1875
1885
1876 line=l2
1886 line=l2
1877
1887
1878
1888
1879 # print "al expand to",line #dbg
1889 # print "al expand to",line #dbg
1880 else:
1890 else:
1881 break
1891 break
1882
1892
1883 return line
1893 return line
1884
1894
1885 def transform_alias(self, alias,rest=''):
1895 def transform_alias(self, alias,rest=''):
1886 """ Transform alias to system command string.
1896 """ Transform alias to system command string.
1887 """
1897 """
1888 trg = self.alias_table[alias]
1898 trg = self.alias_table[alias]
1889
1899
1890 nargs,cmd = trg
1900 nargs,cmd = trg
1891 # print trg #dbg
1901 # print trg #dbg
1892 if ' ' in cmd and os.path.isfile(cmd):
1902 if ' ' in cmd and os.path.isfile(cmd):
1893 cmd = '"%s"' % cmd
1903 cmd = '"%s"' % cmd
1894
1904
1895 # Expand the %l special to be the user's input line
1905 # Expand the %l special to be the user's input line
1896 if cmd.find('%l') >= 0:
1906 if cmd.find('%l') >= 0:
1897 cmd = cmd.replace('%l',rest)
1907 cmd = cmd.replace('%l',rest)
1898 rest = ''
1908 rest = ''
1899 if nargs==0:
1909 if nargs==0:
1900 # Simple, argument-less aliases
1910 # Simple, argument-less aliases
1901 cmd = '%s %s' % (cmd,rest)
1911 cmd = '%s %s' % (cmd,rest)
1902 else:
1912 else:
1903 # Handle aliases with positional arguments
1913 # Handle aliases with positional arguments
1904 args = rest.split(None,nargs)
1914 args = rest.split(None,nargs)
1905 if len(args)< nargs:
1915 if len(args)< nargs:
1906 error('Alias <%s> requires %s arguments, %s given.' %
1916 error('Alias <%s> requires %s arguments, %s given.' %
1907 (alias,nargs,len(args)))
1917 (alias,nargs,len(args)))
1908 return None
1918 return None
1909 cmd = '%s %s' % (cmd % tuple(args[:nargs]),' '.join(args[nargs:]))
1919 cmd = '%s %s' % (cmd % tuple(args[:nargs]),' '.join(args[nargs:]))
1910 # Now call the macro, evaluating in the user's namespace
1920 # Now call the macro, evaluating in the user's namespace
1911 #print 'new command: <%r>' % cmd # dbg
1921 #print 'new command: <%r>' % cmd # dbg
1912 return cmd
1922 return cmd
1913
1923
1914 def call_alias(self,alias,rest=''):
1924 def call_alias(self,alias,rest=''):
1915 """Call an alias given its name and the rest of the line.
1925 """Call an alias given its name and the rest of the line.
1916
1926
1917 This is only used to provide backwards compatibility for users of
1927 This is only used to provide backwards compatibility for users of
1918 ipalias(), use of which is not recommended for anymore."""
1928 ipalias(), use of which is not recommended for anymore."""
1919
1929
1920 # Now call the macro, evaluating in the user's namespace
1930 # Now call the macro, evaluating in the user's namespace
1921 cmd = self.transform_alias(alias, rest)
1931 cmd = self.transform_alias(alias, rest)
1922 try:
1932 try:
1923 self.system(cmd)
1933 self.system(cmd)
1924 except:
1934 except:
1925 self.showtraceback()
1935 self.showtraceback()
1926
1936
1927 def indent_current_str(self):
1937 def indent_current_str(self):
1928 """return the current level of indentation as a string"""
1938 """return the current level of indentation as a string"""
1929 return self.indent_current_nsp * ' '
1939 return self.indent_current_nsp * ' '
1930
1940
1931 def autoindent_update(self,line):
1941 def autoindent_update(self,line):
1932 """Keep track of the indent level."""
1942 """Keep track of the indent level."""
1933
1943
1934 #debugx('line')
1944 #debugx('line')
1935 #debugx('self.indent_current_nsp')
1945 #debugx('self.indent_current_nsp')
1936 if self.autoindent:
1946 if self.autoindent:
1937 if line:
1947 if line:
1938 inisp = num_ini_spaces(line)
1948 inisp = num_ini_spaces(line)
1939 if inisp < self.indent_current_nsp:
1949 if inisp < self.indent_current_nsp:
1940 self.indent_current_nsp = inisp
1950 self.indent_current_nsp = inisp
1941
1951
1942 if line[-1] == ':':
1952 if line[-1] == ':':
1943 self.indent_current_nsp += 4
1953 self.indent_current_nsp += 4
1944 elif dedent_re.match(line):
1954 elif dedent_re.match(line):
1945 self.indent_current_nsp -= 4
1955 self.indent_current_nsp -= 4
1946 else:
1956 else:
1947 self.indent_current_nsp = 0
1957 self.indent_current_nsp = 0
1948
1958
1949 def runlines(self,lines):
1959 def runlines(self,lines):
1950 """Run a string of one or more lines of source.
1960 """Run a string of one or more lines of source.
1951
1961
1952 This method is capable of running a string containing multiple source
1962 This method is capable of running a string containing multiple source
1953 lines, as if they had been entered at the IPython prompt. Since it
1963 lines, as if they had been entered at the IPython prompt. Since it
1954 exposes IPython's processing machinery, the given strings can contain
1964 exposes IPython's processing machinery, the given strings can contain
1955 magic calls (%magic), special shell access (!cmd), etc."""
1965 magic calls (%magic), special shell access (!cmd), etc."""
1956
1966
1957 # We must start with a clean buffer, in case this is run from an
1967 # We must start with a clean buffer, in case this is run from an
1958 # interactive IPython session (via a magic, for example).
1968 # interactive IPython session (via a magic, for example).
1959 self.resetbuffer()
1969 self.resetbuffer()
1960 lines = lines.split('\n')
1970 lines = lines.split('\n')
1961 more = 0
1971 more = 0
1962
1972
1963 for line in lines:
1973 for line in lines:
1964 # skip blank lines so we don't mess up the prompt counter, but do
1974 # skip blank lines so we don't mess up the prompt counter, but do
1965 # NOT skip even a blank line if we are in a code block (more is
1975 # NOT skip even a blank line if we are in a code block (more is
1966 # true)
1976 # true)
1967
1977
1968
1978
1969 if line or more:
1979 if line or more:
1970 # push to raw history, so hist line numbers stay in sync
1980 # push to raw history, so hist line numbers stay in sync
1971 self.input_hist_raw.append("# " + line + "\n")
1981 self.input_hist_raw.append("# " + line + "\n")
1972 more = self.push(self.prefilter(line,more))
1982 more = self.push(self.prefilter(line,more))
1973 # IPython's runsource returns None if there was an error
1983 # IPython's runsource returns None if there was an error
1974 # compiling the code. This allows us to stop processing right
1984 # compiling the code. This allows us to stop processing right
1975 # away, so the user gets the error message at the right place.
1985 # away, so the user gets the error message at the right place.
1976 if more is None:
1986 if more is None:
1977 break
1987 break
1978 else:
1988 else:
1979 self.input_hist_raw.append("\n")
1989 self.input_hist_raw.append("\n")
1980 # final newline in case the input didn't have it, so that the code
1990 # final newline in case the input didn't have it, so that the code
1981 # actually does get executed
1991 # actually does get executed
1982 if more:
1992 if more:
1983 self.push('\n')
1993 self.push('\n')
1984
1994
1985 def runsource(self, source, filename='<input>', symbol='single'):
1995 def runsource(self, source, filename='<input>', symbol='single'):
1986 """Compile and run some source in the interpreter.
1996 """Compile and run some source in the interpreter.
1987
1997
1988 Arguments are as for compile_command().
1998 Arguments are as for compile_command().
1989
1999
1990 One several things can happen:
2000 One several things can happen:
1991
2001
1992 1) The input is incorrect; compile_command() raised an
2002 1) The input is incorrect; compile_command() raised an
1993 exception (SyntaxError or OverflowError). A syntax traceback
2003 exception (SyntaxError or OverflowError). A syntax traceback
1994 will be printed by calling the showsyntaxerror() method.
2004 will be printed by calling the showsyntaxerror() method.
1995
2005
1996 2) The input is incomplete, and more input is required;
2006 2) The input is incomplete, and more input is required;
1997 compile_command() returned None. Nothing happens.
2007 compile_command() returned None. Nothing happens.
1998
2008
1999 3) The input is complete; compile_command() returned a code
2009 3) The input is complete; compile_command() returned a code
2000 object. The code is executed by calling self.runcode() (which
2010 object. The code is executed by calling self.runcode() (which
2001 also handles run-time exceptions, except for SystemExit).
2011 also handles run-time exceptions, except for SystemExit).
2002
2012
2003 The return value is:
2013 The return value is:
2004
2014
2005 - True in case 2
2015 - True in case 2
2006
2016
2007 - False in the other cases, unless an exception is raised, where
2017 - False in the other cases, unless an exception is raised, where
2008 None is returned instead. This can be used by external callers to
2018 None is returned instead. This can be used by external callers to
2009 know whether to continue feeding input or not.
2019 know whether to continue feeding input or not.
2010
2020
2011 The return value can be used to decide whether to use sys.ps1 or
2021 The return value can be used to decide whether to use sys.ps1 or
2012 sys.ps2 to prompt the next line."""
2022 sys.ps2 to prompt the next line."""
2013
2023
2014 # if the source code has leading blanks, add 'if 1:\n' to it
2024 # if the source code has leading blanks, add 'if 1:\n' to it
2015 # this allows execution of indented pasted code. It is tempting
2025 # this allows execution of indented pasted code. It is tempting
2016 # to add '\n' at the end of source to run commands like ' a=1'
2026 # to add '\n' at the end of source to run commands like ' a=1'
2017 # directly, but this fails for more complicated scenarios
2027 # directly, but this fails for more complicated scenarios
2018 source=source.encode(self.stdin_encoding)
2028 source=source.encode(self.stdin_encoding)
2019 if source[:1] in [' ', '\t']:
2029 if source[:1] in [' ', '\t']:
2020 source = 'if 1:\n%s' % source
2030 source = 'if 1:\n%s' % source
2021
2031
2022 try:
2032 try:
2023 code = self.compile(source,filename,symbol)
2033 code = self.compile(source,filename,symbol)
2024 except (OverflowError, SyntaxError, ValueError, TypeError):
2034 except (OverflowError, SyntaxError, ValueError, TypeError):
2025 # Case 1
2035 # Case 1
2026 self.showsyntaxerror(filename)
2036 self.showsyntaxerror(filename)
2027 return None
2037 return None
2028
2038
2029 if code is None:
2039 if code is None:
2030 # Case 2
2040 # Case 2
2031 return True
2041 return True
2032
2042
2033 # Case 3
2043 # Case 3
2034 # We store the code object so that threaded shells and
2044 # We store the code object so that threaded shells and
2035 # custom exception handlers can access all this info if needed.
2045 # custom exception handlers can access all this info if needed.
2036 # The source corresponding to this can be obtained from the
2046 # The source corresponding to this can be obtained from the
2037 # buffer attribute as '\n'.join(self.buffer).
2047 # buffer attribute as '\n'.join(self.buffer).
2038 self.code_to_run = code
2048 self.code_to_run = code
2039 # now actually execute the code object
2049 # now actually execute the code object
2040 if self.runcode(code) == 0:
2050 if self.runcode(code) == 0:
2041 return False
2051 return False
2042 else:
2052 else:
2043 return None
2053 return None
2044
2054
2045 def runcode(self,code_obj):
2055 def runcode(self,code_obj):
2046 """Execute a code object.
2056 """Execute a code object.
2047
2057
2048 When an exception occurs, self.showtraceback() is called to display a
2058 When an exception occurs, self.showtraceback() is called to display a
2049 traceback.
2059 traceback.
2050
2060
2051 Return value: a flag indicating whether the code to be run completed
2061 Return value: a flag indicating whether the code to be run completed
2052 successfully:
2062 successfully:
2053
2063
2054 - 0: successful execution.
2064 - 0: successful execution.
2055 - 1: an error occurred.
2065 - 1: an error occurred.
2056 """
2066 """
2057
2067
2058 # Set our own excepthook in case the user code tries to call it
2068 # Set our own excepthook in case the user code tries to call it
2059 # directly, so that the IPython crash handler doesn't get triggered
2069 # directly, so that the IPython crash handler doesn't get triggered
2060 old_excepthook,sys.excepthook = sys.excepthook, self.excepthook
2070 old_excepthook,sys.excepthook = sys.excepthook, self.excepthook
2061
2071
2062 # we save the original sys.excepthook in the instance, in case config
2072 # we save the original sys.excepthook in the instance, in case config
2063 # code (such as magics) needs access to it.
2073 # code (such as magics) needs access to it.
2064 self.sys_excepthook = old_excepthook
2074 self.sys_excepthook = old_excepthook
2065 outflag = 1 # happens in more places, so it's easier as default
2075 outflag = 1 # happens in more places, so it's easier as default
2066 try:
2076 try:
2067 try:
2077 try:
2068 self.hooks.pre_runcode_hook()
2078 self.hooks.pre_runcode_hook()
2069 # Embedded instances require separate global/local namespaces
2079 # Embedded instances require separate global/local namespaces
2070 # so they can see both the surrounding (local) namespace and
2080 # so they can see both the surrounding (local) namespace and
2071 # the module-level globals when called inside another function.
2081 # the module-level globals when called inside another function.
2072 if self.embedded:
2082 if self.embedded:
2073 exec code_obj in self.user_global_ns, self.user_ns
2083 exec code_obj in self.user_global_ns, self.user_ns
2074 # Normal (non-embedded) instances should only have a single
2084 # Normal (non-embedded) instances should only have a single
2075 # namespace for user code execution, otherwise functions won't
2085 # namespace for user code execution, otherwise functions won't
2076 # see interactive top-level globals.
2086 # see interactive top-level globals.
2077 else:
2087 else:
2078 exec code_obj in self.user_ns
2088 exec code_obj in self.user_ns
2079 finally:
2089 finally:
2080 # Reset our crash handler in place
2090 # Reset our crash handler in place
2081 sys.excepthook = old_excepthook
2091 sys.excepthook = old_excepthook
2082 except SystemExit:
2092 except SystemExit:
2083 self.resetbuffer()
2093 self.resetbuffer()
2084 self.showtraceback()
2094 self.showtraceback()
2085 warn("Type %exit or %quit to exit IPython "
2095 warn("Type %exit or %quit to exit IPython "
2086 "(%Exit or %Quit do so unconditionally).",level=1)
2096 "(%Exit or %Quit do so unconditionally).",level=1)
2087 except self.custom_exceptions:
2097 except self.custom_exceptions:
2088 etype,value,tb = sys.exc_info()
2098 etype,value,tb = sys.exc_info()
2089 self.CustomTB(etype,value,tb)
2099 self.CustomTB(etype,value,tb)
2090 except:
2100 except:
2091 self.showtraceback()
2101 self.showtraceback()
2092 else:
2102 else:
2093 outflag = 0
2103 outflag = 0
2094 if softspace(sys.stdout, 0):
2104 if softspace(sys.stdout, 0):
2095 print
2105 print
2096 # Flush out code object which has been run (and source)
2106 # Flush out code object which has been run (and source)
2097 self.code_to_run = None
2107 self.code_to_run = None
2098 return outflag
2108 return outflag
2099
2109
2100 def push(self, line):
2110 def push(self, line):
2101 """Push a line to the interpreter.
2111 """Push a line to the interpreter.
2102
2112
2103 The line should not have a trailing newline; it may have
2113 The line should not have a trailing newline; it may have
2104 internal newlines. The line is appended to a buffer and the
2114 internal newlines. The line is appended to a buffer and the
2105 interpreter's runsource() method is called with the
2115 interpreter's runsource() method is called with the
2106 concatenated contents of the buffer as source. If this
2116 concatenated contents of the buffer as source. If this
2107 indicates that the command was executed or invalid, the buffer
2117 indicates that the command was executed or invalid, the buffer
2108 is reset; otherwise, the command is incomplete, and the buffer
2118 is reset; otherwise, the command is incomplete, and the buffer
2109 is left as it was after the line was appended. The return
2119 is left as it was after the line was appended. The return
2110 value is 1 if more input is required, 0 if the line was dealt
2120 value is 1 if more input is required, 0 if the line was dealt
2111 with in some way (this is the same as runsource()).
2121 with in some way (this is the same as runsource()).
2112 """
2122 """
2113
2123
2114 # autoindent management should be done here, and not in the
2124 # autoindent management should be done here, and not in the
2115 # interactive loop, since that one is only seen by keyboard input. We
2125 # interactive loop, since that one is only seen by keyboard input. We
2116 # need this done correctly even for code run via runlines (which uses
2126 # need this done correctly even for code run via runlines (which uses
2117 # push).
2127 # push).
2118
2128
2119 #print 'push line: <%s>' % line # dbg
2129 #print 'push line: <%s>' % line # dbg
2120 for subline in line.splitlines():
2130 for subline in line.splitlines():
2121 self.autoindent_update(subline)
2131 self.autoindent_update(subline)
2122 self.buffer.append(line)
2132 self.buffer.append(line)
2123 more = self.runsource('\n'.join(self.buffer), self.filename)
2133 more = self.runsource('\n'.join(self.buffer), self.filename)
2124 if not more:
2134 if not more:
2125 self.resetbuffer()
2135 self.resetbuffer()
2126 return more
2136 return more
2127
2137
2128 def split_user_input(self, line):
2138 def split_user_input(self, line):
2129 # This is really a hold-over to support ipapi and some extensions
2139 # This is really a hold-over to support ipapi and some extensions
2130 return prefilter.splitUserInput(line)
2140 return prefilter.splitUserInput(line)
2131
2141
2132 def resetbuffer(self):
2142 def resetbuffer(self):
2133 """Reset the input buffer."""
2143 """Reset the input buffer."""
2134 self.buffer[:] = []
2144 self.buffer[:] = []
2135
2145
2136 def raw_input(self,prompt='',continue_prompt=False):
2146 def raw_input(self,prompt='',continue_prompt=False):
2137 """Write a prompt and read a line.
2147 """Write a prompt and read a line.
2138
2148
2139 The returned line does not include the trailing newline.
2149 The returned line does not include the trailing newline.
2140 When the user enters the EOF key sequence, EOFError is raised.
2150 When the user enters the EOF key sequence, EOFError is raised.
2141
2151
2142 Optional inputs:
2152 Optional inputs:
2143
2153
2144 - prompt(''): a string to be printed to prompt the user.
2154 - prompt(''): a string to be printed to prompt the user.
2145
2155
2146 - continue_prompt(False): whether this line is the first one or a
2156 - continue_prompt(False): whether this line is the first one or a
2147 continuation in a sequence of inputs.
2157 continuation in a sequence of inputs.
2148 """
2158 """
2149
2159
2150 # Code run by the user may have modified the readline completer state.
2160 # Code run by the user may have modified the readline completer state.
2151 # We must ensure that our completer is back in place.
2161 # We must ensure that our completer is back in place.
2152 if self.has_readline:
2162 if self.has_readline:
2153 self.set_completer()
2163 self.set_completer()
2154
2164
2155 try:
2165 try:
2156 line = raw_input_original(prompt).decode(self.stdin_encoding)
2166 line = raw_input_original(prompt).decode(self.stdin_encoding)
2157 except ValueError:
2167 except ValueError:
2158 warn("\n********\nYou or a %run:ed script called sys.stdin.close()"
2168 warn("\n********\nYou or a %run:ed script called sys.stdin.close()"
2159 " or sys.stdout.close()!\nExiting IPython!")
2169 " or sys.stdout.close()!\nExiting IPython!")
2160 self.exit_now = True
2170 self.exit_now = True
2161 return ""
2171 return ""
2162
2172
2163 # Try to be reasonably smart about not re-indenting pasted input more
2173 # Try to be reasonably smart about not re-indenting pasted input more
2164 # than necessary. We do this by trimming out the auto-indent initial
2174 # than necessary. We do this by trimming out the auto-indent initial
2165 # spaces, if the user's actual input started itself with whitespace.
2175 # spaces, if the user's actual input started itself with whitespace.
2166 #debugx('self.buffer[-1]')
2176 #debugx('self.buffer[-1]')
2167
2177
2168 if self.autoindent:
2178 if self.autoindent:
2169 if num_ini_spaces(line) > self.indent_current_nsp:
2179 if num_ini_spaces(line) > self.indent_current_nsp:
2170 line = line[self.indent_current_nsp:]
2180 line = line[self.indent_current_nsp:]
2171 self.indent_current_nsp = 0
2181 self.indent_current_nsp = 0
2172
2182
2173 # store the unfiltered input before the user has any chance to modify
2183 # store the unfiltered input before the user has any chance to modify
2174 # it.
2184 # it.
2175 if line.strip():
2185 if line.strip():
2176 if continue_prompt:
2186 if continue_prompt:
2177 self.input_hist_raw[-1] += '%s\n' % line
2187 self.input_hist_raw[-1] += '%s\n' % line
2178 if self.has_readline: # and some config option is set?
2188 if self.has_readline: # and some config option is set?
2179 try:
2189 try:
2180 histlen = self.readline.get_current_history_length()
2190 histlen = self.readline.get_current_history_length()
2181 if histlen > 1:
2191 if histlen > 1:
2182 newhist = self.input_hist_raw[-1].rstrip()
2192 newhist = self.input_hist_raw[-1].rstrip()
2183 self.readline.remove_history_item(histlen-1)
2193 self.readline.remove_history_item(histlen-1)
2184 self.readline.replace_history_item(histlen-2,
2194 self.readline.replace_history_item(histlen-2,
2185 newhist.encode(self.stdin_encoding))
2195 newhist.encode(self.stdin_encoding))
2186 except AttributeError:
2196 except AttributeError:
2187 pass # re{move,place}_history_item are new in 2.4.
2197 pass # re{move,place}_history_item are new in 2.4.
2188 else:
2198 else:
2189 self.input_hist_raw.append('%s\n' % line)
2199 self.input_hist_raw.append('%s\n' % line)
2190 # only entries starting at first column go to shadow history
2200 # only entries starting at first column go to shadow history
2191 if line.lstrip() == line:
2201 if line.lstrip() == line:
2192 self.shadowhist.add(line.strip())
2202 self.shadowhist.add(line.strip())
2193 elif not continue_prompt:
2203 elif not continue_prompt:
2194 self.input_hist_raw.append('\n')
2204 self.input_hist_raw.append('\n')
2195 try:
2205 try:
2196 lineout = self.prefilter(line,continue_prompt)
2206 lineout = self.prefilter(line,continue_prompt)
2197 except:
2207 except:
2198 # blanket except, in case a user-defined prefilter crashes, so it
2208 # blanket except, in case a user-defined prefilter crashes, so it
2199 # can't take all of ipython with it.
2209 # can't take all of ipython with it.
2200 self.showtraceback()
2210 self.showtraceback()
2201 return ''
2211 return ''
2202 else:
2212 else:
2203 return lineout
2213 return lineout
2204
2214
2205 def _prefilter(self, line, continue_prompt):
2215 def _prefilter(self, line, continue_prompt):
2206 """Calls different preprocessors, depending on the form of line."""
2216 """Calls different preprocessors, depending on the form of line."""
2207
2217
2208 # All handlers *must* return a value, even if it's blank ('').
2218 # All handlers *must* return a value, even if it's blank ('').
2209
2219
2210 # Lines are NOT logged here. Handlers should process the line as
2220 # Lines are NOT logged here. Handlers should process the line as
2211 # needed, update the cache AND log it (so that the input cache array
2221 # needed, update the cache AND log it (so that the input cache array
2212 # stays synced).
2222 # stays synced).
2213
2223
2214 #.....................................................................
2224 #.....................................................................
2215 # Code begins
2225 # Code begins
2216
2226
2217 #if line.startswith('%crash'): raise RuntimeError,'Crash now!' # dbg
2227 #if line.startswith('%crash'): raise RuntimeError,'Crash now!' # dbg
2218
2228
2219 # save the line away in case we crash, so the post-mortem handler can
2229 # save the line away in case we crash, so the post-mortem handler can
2220 # record it
2230 # record it
2221 self._last_input_line = line
2231 self._last_input_line = line
2222
2232
2223 #print '***line: <%s>' % line # dbg
2233 #print '***line: <%s>' % line # dbg
2224
2234
2225 if not line:
2235 if not line:
2226 # Return immediately on purely empty lines, so that if the user
2236 # Return immediately on purely empty lines, so that if the user
2227 # previously typed some whitespace that started a continuation
2237 # previously typed some whitespace that started a continuation
2228 # prompt, he can break out of that loop with just an empty line.
2238 # prompt, he can break out of that loop with just an empty line.
2229 # This is how the default python prompt works.
2239 # This is how the default python prompt works.
2230
2240
2231 # Only return if the accumulated input buffer was just whitespace!
2241 # Only return if the accumulated input buffer was just whitespace!
2232 if ''.join(self.buffer).isspace():
2242 if ''.join(self.buffer).isspace():
2233 self.buffer[:] = []
2243 self.buffer[:] = []
2234 return ''
2244 return ''
2235
2245
2236 line_info = prefilter.LineInfo(line, continue_prompt)
2246 line_info = prefilter.LineInfo(line, continue_prompt)
2237
2247
2238 # the input history needs to track even empty lines
2248 # the input history needs to track even empty lines
2239 stripped = line.strip()
2249 stripped = line.strip()
2240
2250
2241 if not stripped:
2251 if not stripped:
2242 if not continue_prompt:
2252 if not continue_prompt:
2243 self.outputcache.prompt_count -= 1
2253 self.outputcache.prompt_count -= 1
2244 return self.handle_normal(line_info)
2254 return self.handle_normal(line_info)
2245
2255
2246 # print '***cont',continue_prompt # dbg
2256 # print '***cont',continue_prompt # dbg
2247 # special handlers are only allowed for single line statements
2257 # special handlers are only allowed for single line statements
2248 if continue_prompt and not self.rc.multi_line_specials:
2258 if continue_prompt and not self.rc.multi_line_specials:
2249 return self.handle_normal(line_info)
2259 return self.handle_normal(line_info)
2250
2260
2251
2261
2252 # See whether any pre-existing handler can take care of it
2262 # See whether any pre-existing handler can take care of it
2253 rewritten = self.hooks.input_prefilter(stripped)
2263 rewritten = self.hooks.input_prefilter(stripped)
2254 if rewritten != stripped: # ok, some prefilter did something
2264 if rewritten != stripped: # ok, some prefilter did something
2255 rewritten = line_info.pre + rewritten # add indentation
2265 rewritten = line_info.pre + rewritten # add indentation
2256 return self.handle_normal(prefilter.LineInfo(rewritten,
2266 return self.handle_normal(prefilter.LineInfo(rewritten,
2257 continue_prompt))
2267 continue_prompt))
2258
2268
2259 #print 'pre <%s> iFun <%s> rest <%s>' % (pre,iFun,theRest) # dbg
2269 #print 'pre <%s> iFun <%s> rest <%s>' % (pre,iFun,theRest) # dbg
2260
2270
2261 return prefilter.prefilter(line_info, self)
2271 return prefilter.prefilter(line_info, self)
2262
2272
2263
2273
2264 def _prefilter_dumb(self, line, continue_prompt):
2274 def _prefilter_dumb(self, line, continue_prompt):
2265 """simple prefilter function, for debugging"""
2275 """simple prefilter function, for debugging"""
2266 return self.handle_normal(line,continue_prompt)
2276 return self.handle_normal(line,continue_prompt)
2267
2277
2268
2278
2269 def multiline_prefilter(self, line, continue_prompt):
2279 def multiline_prefilter(self, line, continue_prompt):
2270 """ Run _prefilter for each line of input
2280 """ Run _prefilter for each line of input
2271
2281
2272 Covers cases where there are multiple lines in the user entry,
2282 Covers cases where there are multiple lines in the user entry,
2273 which is the case when the user goes back to a multiline history
2283 which is the case when the user goes back to a multiline history
2274 entry and presses enter.
2284 entry and presses enter.
2275
2285
2276 """
2286 """
2277 out = []
2287 out = []
2278 for l in line.rstrip('\n').split('\n'):
2288 for l in line.rstrip('\n').split('\n'):
2279 out.append(self._prefilter(l, continue_prompt))
2289 out.append(self._prefilter(l, continue_prompt))
2280 return '\n'.join(out)
2290 return '\n'.join(out)
2281
2291
2282 # Set the default prefilter() function (this can be user-overridden)
2292 # Set the default prefilter() function (this can be user-overridden)
2283 prefilter = multiline_prefilter
2293 prefilter = multiline_prefilter
2284
2294
2285 def handle_normal(self,line_info):
2295 def handle_normal(self,line_info):
2286 """Handle normal input lines. Use as a template for handlers."""
2296 """Handle normal input lines. Use as a template for handlers."""
2287
2297
2288 # With autoindent on, we need some way to exit the input loop, and I
2298 # With autoindent on, we need some way to exit the input loop, and I
2289 # don't want to force the user to have to backspace all the way to
2299 # don't want to force the user to have to backspace all the way to
2290 # clear the line. The rule will be in this case, that either two
2300 # clear the line. The rule will be in this case, that either two
2291 # lines of pure whitespace in a row, or a line of pure whitespace but
2301 # lines of pure whitespace in a row, or a line of pure whitespace but
2292 # of a size different to the indent level, will exit the input loop.
2302 # of a size different to the indent level, will exit the input loop.
2293 line = line_info.line
2303 line = line_info.line
2294 continue_prompt = line_info.continue_prompt
2304 continue_prompt = line_info.continue_prompt
2295
2305
2296 if (continue_prompt and self.autoindent and line.isspace() and
2306 if (continue_prompt and self.autoindent and line.isspace() and
2297 (0 < abs(len(line) - self.indent_current_nsp) <= 2 or
2307 (0 < abs(len(line) - self.indent_current_nsp) <= 2 or
2298 (self.buffer[-1]).isspace() )):
2308 (self.buffer[-1]).isspace() )):
2299 line = ''
2309 line = ''
2300
2310
2301 self.log(line,line,continue_prompt)
2311 self.log(line,line,continue_prompt)
2302 return line
2312 return line
2303
2313
2304 def handle_alias(self,line_info):
2314 def handle_alias(self,line_info):
2305 """Handle alias input lines. """
2315 """Handle alias input lines. """
2306 tgt = self.alias_table[line_info.iFun]
2316 tgt = self.alias_table[line_info.iFun]
2307 # print "=>",tgt #dbg
2317 # print "=>",tgt #dbg
2308 if callable(tgt):
2318 if callable(tgt):
2309 if '$' in line_info.line:
2319 if '$' in line_info.line:
2310 call_meth = '(_ip, _ip.itpl(%s))'
2320 call_meth = '(_ip, _ip.itpl(%s))'
2311 else:
2321 else:
2312 call_meth = '(_ip,%s)'
2322 call_meth = '(_ip,%s)'
2313 line_out = ("%s_sh.%s" + call_meth) % (line_info.preWhitespace,
2323 line_out = ("%s_sh.%s" + call_meth) % (line_info.preWhitespace,
2314 line_info.iFun,
2324 line_info.iFun,
2315 make_quoted_expr(line_info.line))
2325 make_quoted_expr(line_info.line))
2316 else:
2326 else:
2317 transformed = self.expand_aliases(line_info.iFun,line_info.theRest)
2327 transformed = self.expand_aliases(line_info.iFun,line_info.theRest)
2318
2328
2319 # pre is needed, because it carries the leading whitespace. Otherwise
2329 # pre is needed, because it carries the leading whitespace. Otherwise
2320 # aliases won't work in indented sections.
2330 # aliases won't work in indented sections.
2321 line_out = '%s_ip.system(%s)' % (line_info.preWhitespace,
2331 line_out = '%s_ip.system(%s)' % (line_info.preWhitespace,
2322 make_quoted_expr( transformed ))
2332 make_quoted_expr( transformed ))
2323
2333
2324 self.log(line_info.line,line_out,line_info.continue_prompt)
2334 self.log(line_info.line,line_out,line_info.continue_prompt)
2325 #print 'line out:',line_out # dbg
2335 #print 'line out:',line_out # dbg
2326 return line_out
2336 return line_out
2327
2337
2328 def handle_shell_escape(self, line_info):
2338 def handle_shell_escape(self, line_info):
2329 """Execute the line in a shell, empty return value"""
2339 """Execute the line in a shell, empty return value"""
2330 #print 'line in :', `line` # dbg
2340 #print 'line in :', `line` # dbg
2331 line = line_info.line
2341 line = line_info.line
2332 if line.lstrip().startswith('!!'):
2342 if line.lstrip().startswith('!!'):
2333 # rewrite LineInfo's line, iFun and theRest to properly hold the
2343 # rewrite LineInfo's line, iFun and theRest to properly hold the
2334 # call to %sx and the actual command to be executed, so
2344 # call to %sx and the actual command to be executed, so
2335 # handle_magic can work correctly. Note that this works even if
2345 # handle_magic can work correctly. Note that this works even if
2336 # the line is indented, so it handles multi_line_specials
2346 # the line is indented, so it handles multi_line_specials
2337 # properly.
2347 # properly.
2338 new_rest = line.lstrip()[2:]
2348 new_rest = line.lstrip()[2:]
2339 line_info.line = '%ssx %s' % (self.ESC_MAGIC,new_rest)
2349 line_info.line = '%ssx %s' % (self.ESC_MAGIC,new_rest)
2340 line_info.iFun = 'sx'
2350 line_info.iFun = 'sx'
2341 line_info.theRest = new_rest
2351 line_info.theRest = new_rest
2342 return self.handle_magic(line_info)
2352 return self.handle_magic(line_info)
2343 else:
2353 else:
2344 cmd = line.lstrip().lstrip('!')
2354 cmd = line.lstrip().lstrip('!')
2345 line_out = '%s_ip.system(%s)' % (line_info.preWhitespace,
2355 line_out = '%s_ip.system(%s)' % (line_info.preWhitespace,
2346 make_quoted_expr(cmd))
2356 make_quoted_expr(cmd))
2347 # update cache/log and return
2357 # update cache/log and return
2348 self.log(line,line_out,line_info.continue_prompt)
2358 self.log(line,line_out,line_info.continue_prompt)
2349 return line_out
2359 return line_out
2350
2360
2351 def handle_magic(self, line_info):
2361 def handle_magic(self, line_info):
2352 """Execute magic functions."""
2362 """Execute magic functions."""
2353 iFun = line_info.iFun
2363 iFun = line_info.iFun
2354 theRest = line_info.theRest
2364 theRest = line_info.theRest
2355 cmd = '%s_ip.magic(%s)' % (line_info.preWhitespace,
2365 cmd = '%s_ip.magic(%s)' % (line_info.preWhitespace,
2356 make_quoted_expr(iFun + " " + theRest))
2366 make_quoted_expr(iFun + " " + theRest))
2357 self.log(line_info.line,cmd,line_info.continue_prompt)
2367 self.log(line_info.line,cmd,line_info.continue_prompt)
2358 #print 'in handle_magic, cmd=<%s>' % cmd # dbg
2368 #print 'in handle_magic, cmd=<%s>' % cmd # dbg
2359 return cmd
2369 return cmd
2360
2370
2361 def handle_auto(self, line_info):
2371 def handle_auto(self, line_info):
2362 """Hande lines which can be auto-executed, quoting if requested."""
2372 """Hande lines which can be auto-executed, quoting if requested."""
2363
2373
2364 #print 'pre <%s> iFun <%s> rest <%s>' % (pre,iFun,theRest) # dbg
2365 line = line_info.line
2374 line = line_info.line
2366 iFun = line_info.iFun
2375 iFun = line_info.iFun
2367 theRest = line_info.theRest
2376 theRest = line_info.theRest
2368 pre = line_info.pre
2377 pre = line_info.pre
2369 continue_prompt = line_info.continue_prompt
2378 continue_prompt = line_info.continue_prompt
2370 obj = line_info.ofind(self)['obj']
2379 obj = line_info.ofind(self)['obj']
2371
2380
2381 #print 'pre <%s> iFun <%s> rest <%s>' % (pre,iFun,theRest) # dbg
2382
2372 # This should only be active for single-line input!
2383 # This should only be active for single-line input!
2373 if continue_prompt:
2384 if continue_prompt:
2385 print 'getting out!' # dbg
2374 self.log(line,line,continue_prompt)
2386 self.log(line,line,continue_prompt)
2375 return line
2387 return line
2376
2388
2377 force_auto = isinstance(obj, IPython.ipapi.IPyAutocall)
2389 force_auto = isinstance(obj, IPython.ipapi.IPyAutocall)
2378 auto_rewrite = True
2390 auto_rewrite = True
2379
2391
2380 if pre == self.ESC_QUOTE:
2392 if pre == self.ESC_QUOTE:
2381 # Auto-quote splitting on whitespace
2393 # Auto-quote splitting on whitespace
2382 newcmd = '%s("%s")' % (iFun,'", "'.join(theRest.split()) )
2394 newcmd = '%s("%s")' % (iFun,'", "'.join(theRest.split()) )
2383 elif pre == self.ESC_QUOTE2:
2395 elif pre == self.ESC_QUOTE2:
2384 # Auto-quote whole string
2396 # Auto-quote whole string
2385 newcmd = '%s("%s")' % (iFun,theRest)
2397 newcmd = '%s("%s")' % (iFun,theRest)
2386 elif pre == self.ESC_PAREN:
2398 elif pre == self.ESC_PAREN:
2387 newcmd = '%s(%s)' % (iFun,",".join(theRest.split()))
2399 newcmd = '%s(%s)' % (iFun,",".join(theRest.split()))
2388 else:
2400 else:
2389 # Auto-paren.
2401 # Auto-paren.
2390 # We only apply it to argument-less calls if the autocall
2402 # We only apply it to argument-less calls if the autocall
2391 # parameter is set to 2. We only need to check that autocall is <
2403 # parameter is set to 2. We only need to check that autocall is <
2392 # 2, since this function isn't called unless it's at least 1.
2404 # 2, since this function isn't called unless it's at least 1.
2393 if not theRest and (self.rc.autocall < 2) and not force_auto:
2405 if not theRest and (self.rc.autocall < 2) and not force_auto:
2394 newcmd = '%s %s' % (iFun,theRest)
2406 newcmd = '%s %s' % (iFun,theRest)
2395 auto_rewrite = False
2407 auto_rewrite = False
2396 else:
2408 else:
2397 if not force_auto and theRest.startswith('['):
2409 if not force_auto and theRest.startswith('['):
2398 if hasattr(obj,'__getitem__'):
2410 if hasattr(obj,'__getitem__'):
2399 # Don't autocall in this case: item access for an object
2411 # Don't autocall in this case: item access for an object
2400 # which is BOTH callable and implements __getitem__.
2412 # which is BOTH callable and implements __getitem__.
2401 newcmd = '%s %s' % (iFun,theRest)
2413 newcmd = '%s %s' % (iFun,theRest)
2402 auto_rewrite = False
2414 auto_rewrite = False
2403 else:
2415 else:
2404 # if the object doesn't support [] access, go ahead and
2416 # if the object doesn't support [] access, go ahead and
2405 # autocall
2417 # autocall
2406 newcmd = '%s(%s)' % (iFun.rstrip(),theRest)
2418 newcmd = '%s(%s)' % (iFun.rstrip(),theRest)
2407 elif theRest.endswith(';'):
2419 elif theRest.endswith(';'):
2408 newcmd = '%s(%s);' % (iFun.rstrip(),theRest[:-1])
2420 newcmd = '%s(%s);' % (iFun.rstrip(),theRest[:-1])
2409 else:
2421 else:
2410 newcmd = '%s(%s)' % (iFun.rstrip(), theRest)
2422 newcmd = '%s(%s)' % (iFun.rstrip(), theRest)
2411
2423
2412 if auto_rewrite:
2424 if auto_rewrite:
2413 rw = self.outputcache.prompt1.auto_rewrite() + newcmd
2425 rw = self.outputcache.prompt1.auto_rewrite() + newcmd
2414
2426
2415 try:
2427 try:
2416 # plain ascii works better w/ pyreadline, on some machines, so
2428 # plain ascii works better w/ pyreadline, on some machines, so
2417 # we use it and only print uncolored rewrite if we have unicode
2429 # we use it and only print uncolored rewrite if we have unicode
2418 rw = str(rw)
2430 rw = str(rw)
2419 print >>Term.cout, rw
2431 print >>Term.cout, rw
2420 except UnicodeEncodeError:
2432 except UnicodeEncodeError:
2421 print "-------------->" + newcmd
2433 print "-------------->" + newcmd
2422
2434
2423 # log what is now valid Python, not the actual user input (without the
2435 # log what is now valid Python, not the actual user input (without the
2424 # final newline)
2436 # final newline)
2425 self.log(line,newcmd,continue_prompt)
2437 self.log(line,newcmd,continue_prompt)
2426 return newcmd
2438 return newcmd
2427
2439
2428 def handle_help(self, line_info):
2440 def handle_help(self, line_info):
2429 """Try to get some help for the object.
2441 """Try to get some help for the object.
2430
2442
2431 obj? or ?obj -> basic information.
2443 obj? or ?obj -> basic information.
2432 obj?? or ??obj -> more details.
2444 obj?? or ??obj -> more details.
2433 """
2445 """
2434
2446
2435 line = line_info.line
2447 line = line_info.line
2436 # We need to make sure that we don't process lines which would be
2448 # We need to make sure that we don't process lines which would be
2437 # otherwise valid python, such as "x=1 # what?"
2449 # otherwise valid python, such as "x=1 # what?"
2438 try:
2450 try:
2439 codeop.compile_command(line)
2451 codeop.compile_command(line)
2440 except SyntaxError:
2452 except SyntaxError:
2441 # We should only handle as help stuff which is NOT valid syntax
2453 # We should only handle as help stuff which is NOT valid syntax
2442 if line[0]==self.ESC_HELP:
2454 if line[0]==self.ESC_HELP:
2443 line = line[1:]
2455 line = line[1:]
2444 elif line[-1]==self.ESC_HELP:
2456 elif line[-1]==self.ESC_HELP:
2445 line = line[:-1]
2457 line = line[:-1]
2446 self.log(line,'#?'+line,line_info.continue_prompt)
2458 self.log(line,'#?'+line,line_info.continue_prompt)
2447 if line:
2459 if line:
2448 #print 'line:<%r>' % line # dbg
2460 #print 'line:<%r>' % line # dbg
2449 self.magic_pinfo(line)
2461 self.magic_pinfo(line)
2450 else:
2462 else:
2451 page(self.usage,screen_lines=self.rc.screen_length)
2463 page(self.usage,screen_lines=self.rc.screen_length)
2452 return '' # Empty string is needed here!
2464 return '' # Empty string is needed here!
2453 except:
2465 except:
2454 # Pass any other exceptions through to the normal handler
2466 # Pass any other exceptions through to the normal handler
2455 return self.handle_normal(line_info)
2467 return self.handle_normal(line_info)
2456 else:
2468 else:
2457 # If the code compiles ok, we should handle it normally
2469 # If the code compiles ok, we should handle it normally
2458 return self.handle_normal(line_info)
2470 return self.handle_normal(line_info)
2459
2471
2460 def getapi(self):
2472 def getapi(self):
2461 """ Get an IPApi object for this shell instance
2473 """ Get an IPApi object for this shell instance
2462
2474
2463 Getting an IPApi object is always preferable to accessing the shell
2475 Getting an IPApi object is always preferable to accessing the shell
2464 directly, but this holds true especially for extensions.
2476 directly, but this holds true especially for extensions.
2465
2477
2466 It should always be possible to implement an extension with IPApi
2478 It should always be possible to implement an extension with IPApi
2467 alone. If not, contact maintainer to request an addition.
2479 alone. If not, contact maintainer to request an addition.
2468
2480
2469 """
2481 """
2470 return self.api
2482 return self.api
2471
2483
2472 def handle_emacs(self, line_info):
2484 def handle_emacs(self, line_info):
2473 """Handle input lines marked by python-mode."""
2485 """Handle input lines marked by python-mode."""
2474
2486
2475 # Currently, nothing is done. Later more functionality can be added
2487 # Currently, nothing is done. Later more functionality can be added
2476 # here if needed.
2488 # here if needed.
2477
2489
2478 # The input cache shouldn't be updated
2490 # The input cache shouldn't be updated
2479 return line_info.line
2491 return line_info.line
2480
2492
2481
2493
2482 def mktempfile(self,data=None):
2494 def mktempfile(self,data=None):
2483 """Make a new tempfile and return its filename.
2495 """Make a new tempfile and return its filename.
2484
2496
2485 This makes a call to tempfile.mktemp, but it registers the created
2497 This makes a call to tempfile.mktemp, but it registers the created
2486 filename internally so ipython cleans it up at exit time.
2498 filename internally so ipython cleans it up at exit time.
2487
2499
2488 Optional inputs:
2500 Optional inputs:
2489
2501
2490 - data(None): if data is given, it gets written out to the temp file
2502 - data(None): if data is given, it gets written out to the temp file
2491 immediately, and the file is closed again."""
2503 immediately, and the file is closed again."""
2492
2504
2493 filename = tempfile.mktemp('.py','ipython_edit_')
2505 filename = tempfile.mktemp('.py','ipython_edit_')
2494 self.tempfiles.append(filename)
2506 self.tempfiles.append(filename)
2495
2507
2496 if data:
2508 if data:
2497 tmp_file = open(filename,'w')
2509 tmp_file = open(filename,'w')
2498 tmp_file.write(data)
2510 tmp_file.write(data)
2499 tmp_file.close()
2511 tmp_file.close()
2500 return filename
2512 return filename
2501
2513
2502 def write(self,data):
2514 def write(self,data):
2503 """Write a string to the default output"""
2515 """Write a string to the default output"""
2504 Term.cout.write(data)
2516 Term.cout.write(data)
2505
2517
2506 def write_err(self,data):
2518 def write_err(self,data):
2507 """Write a string to the default error output"""
2519 """Write a string to the default error output"""
2508 Term.cerr.write(data)
2520 Term.cerr.write(data)
2509
2521
2510 def exit(self):
2522 def exit(self):
2511 """Handle interactive exit.
2523 """Handle interactive exit.
2512
2524
2513 This method sets the exit_now attribute."""
2525 This method sets the exit_now attribute."""
2514
2526
2515 if self.rc.confirm_exit:
2527 if self.rc.confirm_exit:
2516 if self.ask_yes_no('Do you really want to exit ([y]/n)?','y'):
2528 if self.ask_yes_no('Do you really want to exit ([y]/n)?','y'):
2517 self.exit_now = True
2529 self.exit_now = True
2518 else:
2530 else:
2519 self.exit_now = True
2531 self.exit_now = True
2520
2532
2521 def safe_execfile(self,fname,*where,**kw):
2533 def safe_execfile(self,fname,*where,**kw):
2522 """A safe version of the builtin execfile().
2534 """A safe version of the builtin execfile().
2523
2535
2524 This version will never throw an exception, and knows how to handle
2536 This version will never throw an exception, and knows how to handle
2525 ipython logs as well.
2537 ipython logs as well.
2526
2538
2527 :Parameters:
2539 :Parameters:
2528 fname : string
2540 fname : string
2529 Name of the file to be executed.
2541 Name of the file to be executed.
2530
2542
2531 where : tuple
2543 where : tuple
2532 One or two namespaces, passed to execfile() as (globals,locals).
2544 One or two namespaces, passed to execfile() as (globals,locals).
2533 If only one is given, it is passed as both.
2545 If only one is given, it is passed as both.
2534
2546
2535 :Keywords:
2547 :Keywords:
2536 islog : boolean (False)
2548 islog : boolean (False)
2537
2549
2538 quiet : boolean (True)
2550 quiet : boolean (True)
2539
2551
2540 exit_ignore : boolean (False)
2552 exit_ignore : boolean (False)
2541 """
2553 """
2542
2554
2543 def syspath_cleanup():
2555 def syspath_cleanup():
2544 """Internal cleanup routine for sys.path."""
2556 """Internal cleanup routine for sys.path."""
2545 if add_dname:
2557 if add_dname:
2546 try:
2558 try:
2547 sys.path.remove(dname)
2559 sys.path.remove(dname)
2548 except ValueError:
2560 except ValueError:
2549 # For some reason the user has already removed it, ignore.
2561 # For some reason the user has already removed it, ignore.
2550 pass
2562 pass
2551
2563
2552 fname = os.path.expanduser(fname)
2564 fname = os.path.expanduser(fname)
2553
2565
2554 # Find things also in current directory. This is needed to mimic the
2566 # Find things also in current directory. This is needed to mimic the
2555 # behavior of running a script from the system command line, where
2567 # behavior of running a script from the system command line, where
2556 # Python inserts the script's directory into sys.path
2568 # Python inserts the script's directory into sys.path
2557 dname = os.path.dirname(os.path.abspath(fname))
2569 dname = os.path.dirname(os.path.abspath(fname))
2558 add_dname = False
2570 add_dname = False
2559 if dname not in sys.path:
2571 if dname not in sys.path:
2560 sys.path.insert(0,dname)
2572 sys.path.insert(0,dname)
2561 add_dname = True
2573 add_dname = True
2562
2574
2563 try:
2575 try:
2564 xfile = open(fname)
2576 xfile = open(fname)
2565 except:
2577 except:
2566 print >> Term.cerr, \
2578 print >> Term.cerr, \
2567 'Could not open file <%s> for safe execution.' % fname
2579 'Could not open file <%s> for safe execution.' % fname
2568 syspath_cleanup()
2580 syspath_cleanup()
2569 return None
2581 return None
2570
2582
2571 kw.setdefault('islog',0)
2583 kw.setdefault('islog',0)
2572 kw.setdefault('quiet',1)
2584 kw.setdefault('quiet',1)
2573 kw.setdefault('exit_ignore',0)
2585 kw.setdefault('exit_ignore',0)
2574
2586
2575 first = xfile.readline()
2587 first = xfile.readline()
2576 loghead = str(self.loghead_tpl).split('\n',1)[0].strip()
2588 loghead = str(self.loghead_tpl).split('\n',1)[0].strip()
2577 xfile.close()
2589 xfile.close()
2578 # line by line execution
2590 # line by line execution
2579 if first.startswith(loghead) or kw['islog']:
2591 if first.startswith(loghead) or kw['islog']:
2580 print 'Loading log file <%s> one line at a time...' % fname
2592 print 'Loading log file <%s> one line at a time...' % fname
2581 if kw['quiet']:
2593 if kw['quiet']:
2582 stdout_save = sys.stdout
2594 stdout_save = sys.stdout
2583 sys.stdout = StringIO.StringIO()
2595 sys.stdout = StringIO.StringIO()
2584 try:
2596 try:
2585 globs,locs = where[0:2]
2597 globs,locs = where[0:2]
2586 except:
2598 except:
2587 try:
2599 try:
2588 globs = locs = where[0]
2600 globs = locs = where[0]
2589 except:
2601 except:
2590 globs = locs = globals()
2602 globs = locs = globals()
2591 badblocks = []
2603 badblocks = []
2592
2604
2593 # we also need to identify indented blocks of code when replaying
2605 # we also need to identify indented blocks of code when replaying
2594 # logs and put them together before passing them to an exec
2606 # logs and put them together before passing them to an exec
2595 # statement. This takes a bit of regexp and look-ahead work in the
2607 # statement. This takes a bit of regexp and look-ahead work in the
2596 # file. It's easiest if we swallow the whole thing in memory
2608 # file. It's easiest if we swallow the whole thing in memory
2597 # first, and manually walk through the lines list moving the
2609 # first, and manually walk through the lines list moving the
2598 # counter ourselves.
2610 # counter ourselves.
2599 indent_re = re.compile('\s+\S')
2611 indent_re = re.compile('\s+\S')
2600 xfile = open(fname)
2612 xfile = open(fname)
2601 filelines = xfile.readlines()
2613 filelines = xfile.readlines()
2602 xfile.close()
2614 xfile.close()
2603 nlines = len(filelines)
2615 nlines = len(filelines)
2604 lnum = 0
2616 lnum = 0
2605 while lnum < nlines:
2617 while lnum < nlines:
2606 line = filelines[lnum]
2618 line = filelines[lnum]
2607 lnum += 1
2619 lnum += 1
2608 # don't re-insert logger status info into cache
2620 # don't re-insert logger status info into cache
2609 if line.startswith('#log#'):
2621 if line.startswith('#log#'):
2610 continue
2622 continue
2611 else:
2623 else:
2612 # build a block of code (maybe a single line) for execution
2624 # build a block of code (maybe a single line) for execution
2613 block = line
2625 block = line
2614 try:
2626 try:
2615 next = filelines[lnum] # lnum has already incremented
2627 next = filelines[lnum] # lnum has already incremented
2616 except:
2628 except:
2617 next = None
2629 next = None
2618 while next and indent_re.match(next):
2630 while next and indent_re.match(next):
2619 block += next
2631 block += next
2620 lnum += 1
2632 lnum += 1
2621 try:
2633 try:
2622 next = filelines[lnum]
2634 next = filelines[lnum]
2623 except:
2635 except:
2624 next = None
2636 next = None
2625 # now execute the block of one or more lines
2637 # now execute the block of one or more lines
2626 try:
2638 try:
2627 exec block in globs,locs
2639 exec block in globs,locs
2628 except SystemExit:
2640 except SystemExit:
2629 pass
2641 pass
2630 except:
2642 except:
2631 badblocks.append(block.rstrip())
2643 badblocks.append(block.rstrip())
2632 if kw['quiet']: # restore stdout
2644 if kw['quiet']: # restore stdout
2633 sys.stdout.close()
2645 sys.stdout.close()
2634 sys.stdout = stdout_save
2646 sys.stdout = stdout_save
2635 print 'Finished replaying log file <%s>' % fname
2647 print 'Finished replaying log file <%s>' % fname
2636 if badblocks:
2648 if badblocks:
2637 print >> sys.stderr, ('\nThe following lines/blocks in file '
2649 print >> sys.stderr, ('\nThe following lines/blocks in file '
2638 '<%s> reported errors:' % fname)
2650 '<%s> reported errors:' % fname)
2639
2651
2640 for badline in badblocks:
2652 for badline in badblocks:
2641 print >> sys.stderr, badline
2653 print >> sys.stderr, badline
2642 else: # regular file execution
2654 else: # regular file execution
2643 try:
2655 try:
2644 if sys.platform == 'win32' and sys.version_info < (2,5,1):
2656 if sys.platform == 'win32' and sys.version_info < (2,5,1):
2645 # Work around a bug in Python for Windows. The bug was
2657 # Work around a bug in Python for Windows. The bug was
2646 # fixed in in Python 2.5 r54159 and 54158, but that's still
2658 # fixed in in Python 2.5 r54159 and 54158, but that's still
2647 # SVN Python as of March/07. For details, see:
2659 # SVN Python as of March/07. For details, see:
2648 # http://projects.scipy.org/ipython/ipython/ticket/123
2660 # http://projects.scipy.org/ipython/ipython/ticket/123
2649 try:
2661 try:
2650 globs,locs = where[0:2]
2662 globs,locs = where[0:2]
2651 except:
2663 except:
2652 try:
2664 try:
2653 globs = locs = where[0]
2665 globs = locs = where[0]
2654 except:
2666 except:
2655 globs = locs = globals()
2667 globs = locs = globals()
2656 exec file(fname) in globs,locs
2668 exec file(fname) in globs,locs
2657 else:
2669 else:
2658 execfile(fname,*where)
2670 execfile(fname,*where)
2659 except SyntaxError:
2671 except SyntaxError:
2660 self.showsyntaxerror()
2672 self.showsyntaxerror()
2661 warn('Failure executing file: <%s>' % fname)
2673 warn('Failure executing file: <%s>' % fname)
2662 except SystemExit,status:
2674 except SystemExit,status:
2663 # Code that correctly sets the exit status flag to success (0)
2675 # Code that correctly sets the exit status flag to success (0)
2664 # shouldn't be bothered with a traceback. Note that a plain
2676 # shouldn't be bothered with a traceback. Note that a plain
2665 # sys.exit() does NOT set the message to 0 (it's empty) so that
2677 # sys.exit() does NOT set the message to 0 (it's empty) so that
2666 # will still get a traceback. Note that the structure of the
2678 # will still get a traceback. Note that the structure of the
2667 # SystemExit exception changed between Python 2.4 and 2.5, so
2679 # SystemExit exception changed between Python 2.4 and 2.5, so
2668 # the checks must be done in a version-dependent way.
2680 # the checks must be done in a version-dependent way.
2669 show = False
2681 show = False
2670
2682
2671 if sys.version_info[:2] > (2,5):
2683 if sys.version_info[:2] > (2,5):
2672 if status.message!=0 and not kw['exit_ignore']:
2684 if status.message!=0 and not kw['exit_ignore']:
2673 show = True
2685 show = True
2674 else:
2686 else:
2675 if status.code and not kw['exit_ignore']:
2687 if status.code and not kw['exit_ignore']:
2676 show = True
2688 show = True
2677 if show:
2689 if show:
2678 self.showtraceback()
2690 self.showtraceback()
2679 warn('Failure executing file: <%s>' % fname)
2691 warn('Failure executing file: <%s>' % fname)
2680 except:
2692 except:
2681 self.showtraceback()
2693 self.showtraceback()
2682 warn('Failure executing file: <%s>' % fname)
2694 warn('Failure executing file: <%s>' % fname)
2683
2695
2684 syspath_cleanup()
2696 syspath_cleanup()
2685
2697
2686 #************************* end of file <iplib.py> *****************************
2698 #************************* end of file <iplib.py> *****************************
@@ -1,406 +1,406 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Mimic C structs with lots of extra functionality.
2 """Mimic C structs with lots of extra functionality.
3
3
4 $Id: ipstruct.py 1950 2006-11-28 19:15:35Z vivainio $"""
4 $Id: ipstruct.py 1950 2006-11-28 19:15:35Z vivainio $"""
5
5
6 #*****************************************************************************
6 #*****************************************************************************
7 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
7 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
8 #
8 #
9 # Distributed under the terms of the BSD License. The full license is in
9 # Distributed under the terms of the BSD License. The full license is in
10 # the file COPYING, distributed as part of this software.
10 # the file COPYING, distributed as part of this software.
11 #*****************************************************************************
11 #*****************************************************************************
12
12
13 from IPython import Release
13 from IPython import Release
14 __author__ = '%s <%s>' % Release.authors['Fernando']
14 __author__ = '%s <%s>' % Release.authors['Fernando']
15 __license__ = Release.license
15 __license__ = Release.license
16
16
17 __all__ = ['Struct']
17 __all__ = ['Struct']
18
18
19 import types
19 import types
20 import pprint
20 import pprint
21
21
22 from IPython.genutils import list2dict2
22 from IPython.genutils import list2dict2
23
23
24 class Struct:
24 class Struct:
25 """Class to mimic C structs but also provide convenient dictionary-like
25 """Class to mimic C structs but also provide convenient dictionary-like
26 functionality.
26 functionality.
27
27
28 Instances can be initialized with a dictionary, a list of key=value pairs
28 Instances can be initialized with a dictionary, a list of key=value pairs
29 or both. If both are present, the dictionary must come first.
29 or both. If both are present, the dictionary must come first.
30
30
31 Because Python classes provide direct assignment to their members, it's
31 Because Python classes provide direct assignment to their members, it's
32 easy to overwrite normal methods (S.copy = 1 would destroy access to
32 easy to overwrite normal methods (S.copy = 1 would destroy access to
33 S.copy()). For this reason, all builtin method names are protected and
33 S.copy()). For this reason, all builtin method names are protected and
34 can't be assigned to. An attempt to do s.copy=1 or s['copy']=1 will raise
34 can't be assigned to. An attempt to do s.copy=1 or s['copy']=1 will raise
35 a KeyError exception. If you really want to, you can bypass this
35 a KeyError exception. If you really want to, you can bypass this
36 protection by directly assigning to __dict__: s.__dict__['copy']=1 will
36 protection by directly assigning to __dict__: s.__dict__['copy']=1 will
37 still work. Doing this will break functionality, though. As in most of
37 still work. Doing this will break functionality, though. As in most of
38 Python, namespace protection is weakly enforced, so feel free to shoot
38 Python, namespace protection is weakly enforced, so feel free to shoot
39 yourself if you really want to.
39 yourself if you really want to.
40
40
41 Note that this class uses more memory and is *much* slower than a regular
41 Note that this class uses more memory and is *much* slower than a regular
42 dictionary, so be careful in situations where memory or performance are
42 dictionary, so be careful in situations where memory or performance are
43 critical. But for day to day use it should behave fine. It is particularly
43 critical. But for day to day use it should behave fine. It is particularly
44 convenient for storing configuration data in programs.
44 convenient for storing configuration data in programs.
45
45
46 +,+=,- and -= are implemented. +/+= do merges (non-destructive updates),
46 +,+=,- and -= are implemented. +/+= do merges (non-destructive updates),
47 -/-= remove keys from the original. See the method descripitions.
47 -/-= remove keys from the original. See the method descripitions.
48
48
49 This class allows a quick access syntax: both s.key and s['key'] are
49 This class allows a quick access syntax: both s.key and s['key'] are
50 valid. This syntax has a limitation: each 'key' has to be explicitly
50 valid. This syntax has a limitation: each 'key' has to be explicitly
51 accessed by its original name. The normal s.key syntax doesn't provide
51 accessed by its original name. The normal s.key syntax doesn't provide
52 access to the keys via variables whose values evaluate to the desired
52 access to the keys via variables whose values evaluate to the desired
53 keys. An example should clarify this:
53 keys. An example should clarify this:
54
54
55 Define a dictionary and initialize both with dict and k=v pairs:
55 Define a dictionary and initialize both with dict and k=v pairs:
56 >>> d={'a':1,'b':2}
56 >>> d={'a':1,'b':2}
57 >>> s=Struct(d,hi=10,ho=20)
57 >>> s=Struct(d,hi=10,ho=20)
58
58
59 The return of __repr__ can be used to create a new instance:
59 The return of __repr__ can be used to create a new instance:
60 >>> s
60 >>> s
61 Struct({'__allownew': True, 'a': 1, 'b': 2, 'hi': 10, 'ho': 20})
61 Struct({'__allownew': True, 'a': 1, 'b': 2, 'hi': 10, 'ho': 20})
62
62
63 Note: the special '__allownew' key is used for internal purposes.
63 Note: the special '__allownew' key is used for internal purposes.
64
64
65 __str__ (called by print) shows it's not quite a regular dictionary:
65 __str__ (called by print) shows it's not quite a regular dictionary:
66 >>> print s
66 >>> print s
67 Struct({'__allownew': True, 'a': 1, 'b': 2, 'hi': 10, 'ho': 20})
67 Struct({'__allownew': True, 'a': 1, 'b': 2, 'hi': 10, 'ho': 20})
68
68
69 Access by explicitly named key with dot notation:
69 Access by explicitly named key with dot notation:
70 >>> s.a
70 >>> s.a
71 1
71 1
72
72
73 Or like a dictionary:
73 Or like a dictionary:
74 >>> s['a']
74 >>> s['a']
75 1
75 1
76
76
77 If you want a variable to hold the key value, only dictionary access works:
77 If you want a variable to hold the key value, only dictionary access works:
78 >>> key='hi'
78 >>> key='hi'
79 >>> s.key
79 >>> s.key
80 Traceback (most recent call last):
80 Traceback (most recent call last):
81 File "<stdin>", line 1, in ?
81 File "<stdin>", line 1, in ?
82 AttributeError: Struct instance has no attribute 'key'
82 AttributeError: Struct instance has no attribute 'key'
83
83
84 >>> s[key]
84 >>> s[key]
85 10
85 10
86
86
87 Another limitation of the s.key syntax (and Struct(key=val)
87 Another limitation of the s.key syntax (and Struct(key=val)
88 initialization): keys can't be numbers. But numeric keys can be used and
88 initialization): keys can't be numbers. But numeric keys can be used and
89 accessed using the dictionary syntax. Again, an example:
89 accessed using the dictionary syntax. Again, an example:
90
90
91 This doesn't work:
91 This doesn't work:
92 >> s=Struct(4='hi') #doctest: +IGNORE_EXCEPTION_DETAIL
92 py> s=Struct(4='hi') #doctest: +IGNORE_EXCEPTION_DETAIL
93 Traceback (most recent call last):
93 Traceback (most recent call last):
94 ...
94 ...
95 SyntaxError: keyword can't be an expression
95 SyntaxError: keyword can't be an expression
96
96
97 But this does:
97 But this does:
98 >>> s=Struct()
98 >>> s=Struct()
99 >>> s[4]='hi'
99 >>> s[4]='hi'
100 >>> s
100 >>> s
101 Struct({4: 'hi', '__allownew': True})
101 Struct({4: 'hi', '__allownew': True})
102 >>> s[4]
102 >>> s[4]
103 'hi'
103 'hi'
104 """
104 """
105
105
106 # Attributes to which __setitem__ and __setattr__ will block access.
106 # Attributes to which __setitem__ and __setattr__ will block access.
107 # Note: much of this will be moot in Python 2.2 and will be done in a much
107 # Note: much of this will be moot in Python 2.2 and will be done in a much
108 # cleaner way.
108 # cleaner way.
109 __protected = ('copy dict dictcopy get has_attr has_key items keys '
109 __protected = ('copy dict dictcopy get has_attr has_key items keys '
110 'merge popitem setdefault update values '
110 'merge popitem setdefault update values '
111 '__make_dict __dict_invert ').split()
111 '__make_dict __dict_invert ').split()
112
112
113 def __init__(self,dict=None,**kw):
113 def __init__(self,dict=None,**kw):
114 """Initialize with a dictionary, another Struct, or by giving
114 """Initialize with a dictionary, another Struct, or by giving
115 explicitly the list of attributes.
115 explicitly the list of attributes.
116
116
117 Both can be used, but the dictionary must come first:
117 Both can be used, but the dictionary must come first:
118 Struct(dict), Struct(k1=v1,k2=v2) or Struct(dict,k1=v1,k2=v2).
118 Struct(dict), Struct(k1=v1,k2=v2) or Struct(dict,k1=v1,k2=v2).
119 """
119 """
120 self.__dict__['__allownew'] = True
120 self.__dict__['__allownew'] = True
121 if dict is None:
121 if dict is None:
122 dict = {}
122 dict = {}
123 if isinstance(dict,Struct):
123 if isinstance(dict,Struct):
124 dict = dict.dict()
124 dict = dict.dict()
125 elif dict and type(dict) is not types.DictType:
125 elif dict and type(dict) is not types.DictType:
126 raise TypeError,\
126 raise TypeError,\
127 'Initialize with a dictionary or key=val pairs.'
127 'Initialize with a dictionary or key=val pairs.'
128 dict.update(kw)
128 dict.update(kw)
129 # do the updating by hand to guarantee that we go through the
129 # do the updating by hand to guarantee that we go through the
130 # safety-checked __setitem__
130 # safety-checked __setitem__
131 for k,v in dict.items():
131 for k,v in dict.items():
132 self[k] = v
132 self[k] = v
133
133
134
134
135 def __setitem__(self,key,value):
135 def __setitem__(self,key,value):
136 """Used when struct[key] = val calls are made."""
136 """Used when struct[key] = val calls are made."""
137 if key in Struct.__protected:
137 if key in Struct.__protected:
138 raise KeyError,'Key '+`key`+' is a protected key of class Struct.'
138 raise KeyError,'Key '+`key`+' is a protected key of class Struct.'
139 if not self['__allownew'] and key not in self.__dict__:
139 if not self['__allownew'] and key not in self.__dict__:
140 raise KeyError(
140 raise KeyError(
141 "Can't create unknown attribute %s - Check for typos, or use allow_new_attr to create new attributes!" %
141 "Can't create unknown attribute %s - Check for typos, or use allow_new_attr to create new attributes!" %
142 key)
142 key)
143
143
144 self.__dict__[key] = value
144 self.__dict__[key] = value
145
145
146 def __setattr__(self, key, value):
146 def __setattr__(self, key, value):
147 """Used when struct.key = val calls are made."""
147 """Used when struct.key = val calls are made."""
148 self.__setitem__(key,value)
148 self.__setitem__(key,value)
149
149
150 def __str__(self):
150 def __str__(self):
151 """Gets called by print."""
151 """Gets called by print."""
152
152
153 return 'Struct('+ pprint.pformat(self.__dict__)+')'
153 return 'Struct('+ pprint.pformat(self.__dict__)+')'
154
154
155 def __repr__(self):
155 def __repr__(self):
156 """Gets called by repr.
156 """Gets called by repr.
157
157
158 A Struct can be recreated with S_new=eval(repr(S_old))."""
158 A Struct can be recreated with S_new=eval(repr(S_old))."""
159 return self.__str__()
159 return self.__str__()
160
160
161 def __getitem__(self,key):
161 def __getitem__(self,key):
162 """Allows struct[key] access."""
162 """Allows struct[key] access."""
163 return self.__dict__[key]
163 return self.__dict__[key]
164
164
165 def __contains__(self,key):
165 def __contains__(self,key):
166 """Allows use of the 'in' operator."""
166 """Allows use of the 'in' operator."""
167 return self.__dict__.has_key(key)
167 return self.__dict__.has_key(key)
168
168
169 def __iadd__(self,other):
169 def __iadd__(self,other):
170 """S += S2 is a shorthand for S.merge(S2)."""
170 """S += S2 is a shorthand for S.merge(S2)."""
171 self.merge(other)
171 self.merge(other)
172 return self
172 return self
173
173
174 def __add__(self,other):
174 def __add__(self,other):
175 """S + S2 -> New Struct made form S and S.merge(S2)"""
175 """S + S2 -> New Struct made form S and S.merge(S2)"""
176 Sout = self.copy()
176 Sout = self.copy()
177 Sout.merge(other)
177 Sout.merge(other)
178 return Sout
178 return Sout
179
179
180 def __sub__(self,other):
180 def __sub__(self,other):
181 """Return S1-S2, where all keys in S2 have been deleted (if present)
181 """Return S1-S2, where all keys in S2 have been deleted (if present)
182 from S1."""
182 from S1."""
183 Sout = self.copy()
183 Sout = self.copy()
184 Sout -= other
184 Sout -= other
185 return Sout
185 return Sout
186
186
187 def __isub__(self,other):
187 def __isub__(self,other):
188 """Do in place S = S - S2, meaning all keys in S2 have been deleted
188 """Do in place S = S - S2, meaning all keys in S2 have been deleted
189 (if present) from S1."""
189 (if present) from S1."""
190
190
191 for k in other.keys():
191 for k in other.keys():
192 if self.has_key(k):
192 if self.has_key(k):
193 del self.__dict__[k]
193 del self.__dict__[k]
194
194
195 def __make_dict(self,__loc_data__,**kw):
195 def __make_dict(self,__loc_data__,**kw):
196 "Helper function for update and merge. Return a dict from data."
196 "Helper function for update and merge. Return a dict from data."
197
197
198 if __loc_data__ == None:
198 if __loc_data__ == None:
199 dict = {}
199 dict = {}
200 elif type(__loc_data__) is types.DictType:
200 elif type(__loc_data__) is types.DictType:
201 dict = __loc_data__
201 dict = __loc_data__
202 elif isinstance(__loc_data__,Struct):
202 elif isinstance(__loc_data__,Struct):
203 dict = __loc_data__.__dict__
203 dict = __loc_data__.__dict__
204 else:
204 else:
205 raise TypeError, 'Update with a dict, a Struct or key=val pairs.'
205 raise TypeError, 'Update with a dict, a Struct or key=val pairs.'
206 if kw:
206 if kw:
207 dict.update(kw)
207 dict.update(kw)
208 return dict
208 return dict
209
209
210 def __dict_invert(self,dict):
210 def __dict_invert(self,dict):
211 """Helper function for merge. Takes a dictionary whose values are
211 """Helper function for merge. Takes a dictionary whose values are
212 lists and returns a dict. with the elements of each list as keys and
212 lists and returns a dict. with the elements of each list as keys and
213 the original keys as values."""
213 the original keys as values."""
214
214
215 outdict = {}
215 outdict = {}
216 for k,lst in dict.items():
216 for k,lst in dict.items():
217 if type(lst) is types.StringType:
217 if type(lst) is types.StringType:
218 lst = lst.split()
218 lst = lst.split()
219 for entry in lst:
219 for entry in lst:
220 outdict[entry] = k
220 outdict[entry] = k
221 return outdict
221 return outdict
222
222
223 def clear(self):
223 def clear(self):
224 """Clear all attributes."""
224 """Clear all attributes."""
225 self.__dict__.clear()
225 self.__dict__.clear()
226
226
227 def copy(self):
227 def copy(self):
228 """Return a (shallow) copy of a Struct."""
228 """Return a (shallow) copy of a Struct."""
229 return Struct(self.__dict__.copy())
229 return Struct(self.__dict__.copy())
230
230
231 def dict(self):
231 def dict(self):
232 """Return the Struct's dictionary."""
232 """Return the Struct's dictionary."""
233 return self.__dict__
233 return self.__dict__
234
234
235 def dictcopy(self):
235 def dictcopy(self):
236 """Return a (shallow) copy of the Struct's dictionary."""
236 """Return a (shallow) copy of the Struct's dictionary."""
237 return self.__dict__.copy()
237 return self.__dict__.copy()
238
238
239 def popitem(self):
239 def popitem(self):
240 """S.popitem() -> (k, v), remove and return some (key, value) pair as
240 """S.popitem() -> (k, v), remove and return some (key, value) pair as
241 a 2-tuple; but raise KeyError if S is empty."""
241 a 2-tuple; but raise KeyError if S is empty."""
242 return self.__dict__.popitem()
242 return self.__dict__.popitem()
243
243
244 def update(self,__loc_data__=None,**kw):
244 def update(self,__loc_data__=None,**kw):
245 """Update (merge) with data from another Struct or from a dictionary.
245 """Update (merge) with data from another Struct or from a dictionary.
246 Optionally, one or more key=value pairs can be given at the end for
246 Optionally, one or more key=value pairs can be given at the end for
247 direct update."""
247 direct update."""
248
248
249 # The funny name __loc_data__ is to prevent a common variable name which
249 # The funny name __loc_data__ is to prevent a common variable name which
250 # could be a fieled of a Struct to collide with this parameter. The problem
250 # could be a fieled of a Struct to collide with this parameter. The problem
251 # would arise if the function is called with a keyword with this same name
251 # would arise if the function is called with a keyword with this same name
252 # that a user means to add as a Struct field.
252 # that a user means to add as a Struct field.
253 newdict = Struct.__make_dict(self,__loc_data__,**kw)
253 newdict = Struct.__make_dict(self,__loc_data__,**kw)
254 for k,v in newdict.items():
254 for k,v in newdict.items():
255 self[k] = v
255 self[k] = v
256
256
257 def merge(self,__loc_data__=None,__conflict_solve=None,**kw):
257 def merge(self,__loc_data__=None,__conflict_solve=None,**kw):
258 """S.merge(data,conflict,k=v1,k=v2,...) -> merge data and k=v into S.
258 """S.merge(data,conflict,k=v1,k=v2,...) -> merge data and k=v into S.
259
259
260 This is similar to update(), but much more flexible. First, a dict is
260 This is similar to update(), but much more flexible. First, a dict is
261 made from data+key=value pairs. When merging this dict with the Struct
261 made from data+key=value pairs. When merging this dict with the Struct
262 S, the optional dictionary 'conflict' is used to decide what to do.
262 S, the optional dictionary 'conflict' is used to decide what to do.
263
263
264 If conflict is not given, the default behavior is to preserve any keys
264 If conflict is not given, the default behavior is to preserve any keys
265 with their current value (the opposite of the update method's
265 with their current value (the opposite of the update method's
266 behavior).
266 behavior).
267
267
268 conflict is a dictionary of binary functions which will be used to
268 conflict is a dictionary of binary functions which will be used to
269 solve key conflicts. It must have the following structure:
269 solve key conflicts. It must have the following structure:
270
270
271 conflict == { fn1 : [Skey1,Skey2,...], fn2 : [Skey3], etc }
271 conflict == { fn1 : [Skey1,Skey2,...], fn2 : [Skey3], etc }
272
272
273 Values must be lists or whitespace separated strings which are
273 Values must be lists or whitespace separated strings which are
274 automatically converted to lists of strings by calling string.split().
274 automatically converted to lists of strings by calling string.split().
275
275
276 Each key of conflict is a function which defines a policy for
276 Each key of conflict is a function which defines a policy for
277 resolving conflicts when merging with the input data. Each fn must be
277 resolving conflicts when merging with the input data. Each fn must be
278 a binary function which returns the desired outcome for a key
278 a binary function which returns the desired outcome for a key
279 conflict. These functions will be called as fn(old,new).
279 conflict. These functions will be called as fn(old,new).
280
280
281 An example is probably in order. Suppose you are merging the struct S
281 An example is probably in order. Suppose you are merging the struct S
282 with a dict D and the following conflict policy dict:
282 with a dict D and the following conflict policy dict:
283
283
284 S.merge(D,{fn1:['a','b',4], fn2:'key_c key_d'})
284 S.merge(D,{fn1:['a','b',4], fn2:'key_c key_d'})
285
285
286 If the key 'a' is found in both S and D, the merge method will call:
286 If the key 'a' is found in both S and D, the merge method will call:
287
287
288 S['a'] = fn1(S['a'],D['a'])
288 S['a'] = fn1(S['a'],D['a'])
289
289
290 As a convenience, merge() provides five (the most commonly needed)
290 As a convenience, merge() provides five (the most commonly needed)
291 pre-defined policies: preserve, update, add, add_flip and add_s. The
291 pre-defined policies: preserve, update, add, add_flip and add_s. The
292 easiest explanation is their implementation:
292 easiest explanation is their implementation:
293
293
294 preserve = lambda old,new: old
294 preserve = lambda old,new: old
295 update = lambda old,new: new
295 update = lambda old,new: new
296 add = lambda old,new: old + new
296 add = lambda old,new: old + new
297 add_flip = lambda old,new: new + old # note change of order!
297 add_flip = lambda old,new: new + old # note change of order!
298 add_s = lambda old,new: old + ' ' + new # only works for strings!
298 add_s = lambda old,new: old + ' ' + new # only works for strings!
299
299
300 You can use those four words (as strings) as keys in conflict instead
300 You can use those four words (as strings) as keys in conflict instead
301 of defining them as functions, and the merge method will substitute
301 of defining them as functions, and the merge method will substitute
302 the appropriate functions for you. That is, the call
302 the appropriate functions for you. That is, the call
303
303
304 S.merge(D,{'preserve':'a b c','add':[4,5,'d'],my_function:[6]})
304 S.merge(D,{'preserve':'a b c','add':[4,5,'d'],my_function:[6]})
305
305
306 will automatically substitute the functions preserve and add for the
306 will automatically substitute the functions preserve and add for the
307 names 'preserve' and 'add' before making any function calls.
307 names 'preserve' and 'add' before making any function calls.
308
308
309 For more complicated conflict resolution policies, you still need to
309 For more complicated conflict resolution policies, you still need to
310 construct your own functions. """
310 construct your own functions. """
311
311
312 data_dict = Struct.__make_dict(self,__loc_data__,**kw)
312 data_dict = Struct.__make_dict(self,__loc_data__,**kw)
313
313
314 # policies for conflict resolution: two argument functions which return
314 # policies for conflict resolution: two argument functions which return
315 # the value that will go in the new struct
315 # the value that will go in the new struct
316 preserve = lambda old,new: old
316 preserve = lambda old,new: old
317 update = lambda old,new: new
317 update = lambda old,new: new
318 add = lambda old,new: old + new
318 add = lambda old,new: old + new
319 add_flip = lambda old,new: new + old # note change of order!
319 add_flip = lambda old,new: new + old # note change of order!
320 add_s = lambda old,new: old + ' ' + new
320 add_s = lambda old,new: old + ' ' + new
321
321
322 # default policy is to keep current keys when there's a conflict
322 # default policy is to keep current keys when there's a conflict
323 conflict_solve = list2dict2(self.keys(),default = preserve)
323 conflict_solve = list2dict2(self.keys(),default = preserve)
324
324
325 # the conflict_solve dictionary is given by the user 'inverted': we
325 # the conflict_solve dictionary is given by the user 'inverted': we
326 # need a name-function mapping, it comes as a function -> names
326 # need a name-function mapping, it comes as a function -> names
327 # dict. Make a local copy (b/c we'll make changes), replace user
327 # dict. Make a local copy (b/c we'll make changes), replace user
328 # strings for the three builtin policies and invert it.
328 # strings for the three builtin policies and invert it.
329 if __conflict_solve:
329 if __conflict_solve:
330 inv_conflict_solve_user = __conflict_solve.copy()
330 inv_conflict_solve_user = __conflict_solve.copy()
331 for name, func in [('preserve',preserve), ('update',update),
331 for name, func in [('preserve',preserve), ('update',update),
332 ('add',add), ('add_flip',add_flip),
332 ('add',add), ('add_flip',add_flip),
333 ('add_s',add_s)]:
333 ('add_s',add_s)]:
334 if name in inv_conflict_solve_user.keys():
334 if name in inv_conflict_solve_user.keys():
335 inv_conflict_solve_user[func] = inv_conflict_solve_user[name]
335 inv_conflict_solve_user[func] = inv_conflict_solve_user[name]
336 del inv_conflict_solve_user[name]
336 del inv_conflict_solve_user[name]
337 conflict_solve.update(Struct.__dict_invert(self,inv_conflict_solve_user))
337 conflict_solve.update(Struct.__dict_invert(self,inv_conflict_solve_user))
338 #print 'merge. conflict_solve: '; pprint(conflict_solve) # dbg
338 #print 'merge. conflict_solve: '; pprint(conflict_solve) # dbg
339 #print '*'*50,'in merger. conflict_solver:'; pprint(conflict_solve)
339 #print '*'*50,'in merger. conflict_solver:'; pprint(conflict_solve)
340 for key in data_dict:
340 for key in data_dict:
341 if key not in self:
341 if key not in self:
342 self[key] = data_dict[key]
342 self[key] = data_dict[key]
343 else:
343 else:
344 self[key] = conflict_solve[key](self[key],data_dict[key])
344 self[key] = conflict_solve[key](self[key],data_dict[key])
345
345
346 def has_key(self,key):
346 def has_key(self,key):
347 """Like has_key() dictionary method."""
347 """Like has_key() dictionary method."""
348 return self.__dict__.has_key(key)
348 return self.__dict__.has_key(key)
349
349
350 def hasattr(self,key):
350 def hasattr(self,key):
351 """hasattr function available as a method.
351 """hasattr function available as a method.
352
352
353 Implemented like has_key, to make sure that all available keys in the
353 Implemented like has_key, to make sure that all available keys in the
354 internal dictionary of the Struct appear also as attributes (even
354 internal dictionary of the Struct appear also as attributes (even
355 numeric keys)."""
355 numeric keys)."""
356 return self.__dict__.has_key(key)
356 return self.__dict__.has_key(key)
357
357
358 def items(self):
358 def items(self):
359 """Return the items in the Struct's dictionary, in the same format
359 """Return the items in the Struct's dictionary, in the same format
360 as a call to {}.items()."""
360 as a call to {}.items()."""
361 return self.__dict__.items()
361 return self.__dict__.items()
362
362
363 def keys(self):
363 def keys(self):
364 """Return the keys in the Struct's dictionary, in the same format
364 """Return the keys in the Struct's dictionary, in the same format
365 as a call to {}.keys()."""
365 as a call to {}.keys()."""
366 return self.__dict__.keys()
366 return self.__dict__.keys()
367
367
368 def values(self,keys=None):
368 def values(self,keys=None):
369 """Return the values in the Struct's dictionary, in the same format
369 """Return the values in the Struct's dictionary, in the same format
370 as a call to {}.values().
370 as a call to {}.values().
371
371
372 Can be called with an optional argument keys, which must be a list or
372 Can be called with an optional argument keys, which must be a list or
373 tuple of keys. In this case it returns only the values corresponding
373 tuple of keys. In this case it returns only the values corresponding
374 to those keys (allowing a form of 'slicing' for Structs)."""
374 to those keys (allowing a form of 'slicing' for Structs)."""
375 if not keys:
375 if not keys:
376 return self.__dict__.values()
376 return self.__dict__.values()
377 else:
377 else:
378 ret=[]
378 ret=[]
379 for k in keys:
379 for k in keys:
380 ret.append(self[k])
380 ret.append(self[k])
381 return ret
381 return ret
382
382
383 def get(self,attr,val=None):
383 def get(self,attr,val=None):
384 """S.get(k[,d]) -> S[k] if k in S, else d. d defaults to None."""
384 """S.get(k[,d]) -> S[k] if k in S, else d. d defaults to None."""
385 try:
385 try:
386 return self[attr]
386 return self[attr]
387 except KeyError:
387 except KeyError:
388 return val
388 return val
389
389
390 def setdefault(self,attr,val=None):
390 def setdefault(self,attr,val=None):
391 """S.setdefault(k[,d]) -> S.get(k,d), also set S[k]=d if k not in S"""
391 """S.setdefault(k[,d]) -> S.get(k,d), also set S[k]=d if k not in S"""
392 if not self.has_key(attr):
392 if not self.has_key(attr):
393 self[attr] = val
393 self[attr] = val
394 return self.get(attr,val)
394 return self.get(attr,val)
395
395
396 def allow_new_attr(self, allow = True):
396 def allow_new_attr(self, allow = True):
397 """ Set whether new attributes can be created inside struct
397 """ Set whether new attributes can be created inside struct
398
398
399 This can be used to catch typos by verifying that the attribute user
399 This can be used to catch typos by verifying that the attribute user
400 tries to change already exists in this Struct.
400 tries to change already exists in this Struct.
401 """
401 """
402 self['__allownew'] = allow
402 self['__allownew'] = allow
403
403
404
404
405 # end class Struct
405 # end class Struct
406
406
@@ -1,178 +1,184 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 # -*- test-case-name: IPython.kernel.test.test_contexts -*-
2 # -*- test-case-name: IPython.kernel.test.test_contexts -*-
3 """Context managers for IPython.
3 """Context managers for IPython.
4
4
5 Python 2.5 introduced the `with` statement, which is based on the context
5 Python 2.5 introduced the `with` statement, which is based on the context
6 manager protocol. This module offers a few context managers for common cases,
6 manager protocol. This module offers a few context managers for common cases,
7 which can also be useful as templates for writing new, application-specific
7 which can also be useful as templates for writing new, application-specific
8 managers.
8 managers.
9 """
9 """
10
10
11 from __future__ import with_statement
11 from __future__ import with_statement
12
12
13 __docformat__ = "restructuredtext en"
13 __docformat__ = "restructuredtext en"
14
14
15 #-------------------------------------------------------------------------------
15 #-------------------------------------------------------------------------------
16 # Copyright (C) 2008 The IPython Development Team
16 # Copyright (C) 2008 The IPython Development Team
17 #
17 #
18 # Distributed under the terms of the BSD License. The full license is in
18 # Distributed under the terms of the BSD License. The full license is in
19 # the file COPYING, distributed as part of this software.
19 # the file COPYING, distributed as part of this software.
20 #-------------------------------------------------------------------------------
20 #-------------------------------------------------------------------------------
21
21
22 #-------------------------------------------------------------------------------
22 #-------------------------------------------------------------------------------
23 # Imports
23 # Imports
24 #-------------------------------------------------------------------------------
24 #-------------------------------------------------------------------------------
25
25
26 import linecache
26 import linecache
27 import sys
27 import sys
28
28
29 from twisted.internet.error import ConnectionRefusedError
29 from twisted.internet.error import ConnectionRefusedError
30
30
31 from IPython.ultraTB import _fixed_getinnerframes, findsource
31 from IPython.ultraTB import _fixed_getinnerframes, findsource
32 from IPython import ipapi
32 from IPython import ipapi
33
33
34 from IPython.kernel import error
34 from IPython.kernel import error
35
35
36 #---------------------------------------------------------------------------
36 #---------------------------------------------------------------------------
37 # Utility functions needed by all context managers.
37 # Utility functions needed by all context managers.
38 #---------------------------------------------------------------------------
38 #---------------------------------------------------------------------------
39
39
40 def remote():
40 def remote():
41 """Raises a special exception meant to be caught by context managers.
41 """Raises a special exception meant to be caught by context managers.
42 """
42 """
43 m = 'Special exception to stop local execution of parallel code.'
43 m = 'Special exception to stop local execution of parallel code.'
44 raise error.StopLocalExecution(m)
44 raise error.StopLocalExecution(m)
45
45
46
46
47 def strip_whitespace(source,require_remote=True):
47 def strip_whitespace(source,require_remote=True):
48 """strip leading whitespace from input source.
48 """strip leading whitespace from input source.
49
49
50 :Parameters:
50 :Parameters:
51
51
52 """
52 """
53 remote_mark = 'remote()'
53 remote_mark = 'remote()'
54 # Expand tabs to avoid any confusion.
54 # Expand tabs to avoid any confusion.
55 wsource = [l.expandtabs(4) for l in source]
55 wsource = [l.expandtabs(4) for l in source]
56 # Detect the indentation level
56 # Detect the indentation level
57 done = False
57 done = False
58 for line in wsource:
58 for line in wsource:
59 if line.isspace():
59 if line.isspace():
60 continue
60 continue
61 for col,char in enumerate(line):
61 for col,char in enumerate(line):
62 if char != ' ':
62 if char != ' ':
63 done = True
63 done = True
64 break
64 break
65 if done:
65 if done:
66 break
66 break
67 # Now we know how much leading space there is in the code. Next, we
67 # Now we know how much leading space there is in the code. Next, we
68 # extract up to the first line that has less indentation.
68 # extract up to the first line that has less indentation.
69 # WARNINGS: we skip comments that may be misindented, but we do NOT yet
69 # WARNINGS: we skip comments that may be misindented, but we do NOT yet
70 # detect triple quoted strings that may have flush left text.
70 # detect triple quoted strings that may have flush left text.
71 for lno,line in enumerate(wsource):
71 for lno,line in enumerate(wsource):
72 lead = line[:col]
72 lead = line[:col]
73 if lead.isspace():
73 if lead.isspace():
74 continue
74 continue
75 else:
75 else:
76 if not lead.lstrip().startswith('#'):
76 if not lead.lstrip().startswith('#'):
77 break
77 break
78 # The real 'with' source is up to lno
78 # The real 'with' source is up to lno
79 src_lines = [l[col:] for l in wsource[:lno+1]]
79 src_lines = [l[col:] for l in wsource[:lno+1]]
80
80
81 # Finally, check that the source's first non-comment line begins with the
81 # Finally, check that the source's first non-comment line begins with the
82 # special call 'remote()'
82 # special call 'remote()'
83 if require_remote:
83 if require_remote:
84 for nline,line in enumerate(src_lines):
84 for nline,line in enumerate(src_lines):
85 if line.isspace() or line.startswith('#'):
85 if line.isspace() or line.startswith('#'):
86 continue
86 continue
87 if line.startswith(remote_mark):
87 if line.startswith(remote_mark):
88 break
88 break
89 else:
89 else:
90 raise ValueError('%s call missing at the start of code' %
90 raise ValueError('%s call missing at the start of code' %
91 remote_mark)
91 remote_mark)
92 out_lines = src_lines[nline+1:]
92 out_lines = src_lines[nline+1:]
93 else:
93 else:
94 # If the user specified that the remote() call wasn't mandatory
94 # If the user specified that the remote() call wasn't mandatory
95 out_lines = src_lines
95 out_lines = src_lines
96
96
97 # src = ''.join(out_lines) # dbg
97 # src = ''.join(out_lines) # dbg
98 #print 'SRC:\n<<<<<<<>>>>>>>\n%s<<<<<>>>>>>' % src # dbg
98 #print 'SRC:\n<<<<<<<>>>>>>>\n%s<<<<<>>>>>>' % src # dbg
99 return ''.join(out_lines)
99 return ''.join(out_lines)
100
100
101 class RemoteContextBase(object):
101 class RemoteContextBase(object):
102 def __init__(self):
102 def __init__(self):
103 self.ip = ipapi.get()
103 self.ip = ipapi.get()
104
104
105 def _findsource_file(self,f):
105 def _findsource_file(self,f):
106 linecache.checkcache()
106 linecache.checkcache()
107 s = findsource(f.f_code)
107 s = findsource(f.f_code)
108 lnum = f.f_lineno
108 lnum = f.f_lineno
109 wsource = s[0][f.f_lineno:]
109 wsource = s[0][f.f_lineno:]
110 return strip_whitespace(wsource)
110 return strip_whitespace(wsource)
111
111
112 def _findsource_ipython(self,f):
112 def _findsource_ipython(self,f):
113 from IPython import ipapi
113 from IPython import ipapi
114 self.ip = ipapi.get()
114 self.ip = ipapi.get()
115 buf = self.ip.IP.input_hist_raw[-1].splitlines()[1:]
115 buf = self.ip.IP.input_hist_raw[-1].splitlines()[1:]
116 wsource = [l+'\n' for l in buf ]
116 wsource = [l+'\n' for l in buf ]
117
117
118 return strip_whitespace(wsource)
118 return strip_whitespace(wsource)
119
119
120 def findsource(self,frame):
120 def findsource(self,frame):
121 local_ns = frame.f_locals
121 local_ns = frame.f_locals
122 global_ns = frame.f_globals
122 global_ns = frame.f_globals
123 if frame.f_code.co_filename == '<ipython console>':
123 if frame.f_code.co_filename == '<ipython console>':
124 src = self._findsource_ipython(frame)
124 src = self._findsource_ipython(frame)
125 else:
125 else:
126 src = self._findsource_file(frame)
126 src = self._findsource_file(frame)
127 return src
127 return src
128
128
129 def __enter__(self):
129 def __enter__(self):
130 raise NotImplementedError
130 raise NotImplementedError
131
131
132 def __exit__ (self, etype, value, tb):
132 def __exit__ (self, etype, value, tb):
133 if issubclass(etype,error.StopLocalExecution):
133 if issubclass(etype,error.StopLocalExecution):
134 return True
134 return True
135
135
136 class RemoteMultiEngine(RemoteContextBase):
136 class RemoteMultiEngine(RemoteContextBase):
137 def __init__(self,mec):
137 def __init__(self,mec):
138 self.mec = mec
138 self.mec = mec
139 RemoteContextBase.__init__(self)
139 RemoteContextBase.__init__(self)
140
140
141 def __enter__(self):
141 def __enter__(self):
142 src = self.findsource(sys._getframe(1))
142 src = self.findsource(sys._getframe(1))
143 return self.mec.execute(src)
143 return self.mec.execute(src)
144
144
145
145
146 # XXX - Temporary hackish testing, we'll move this into proper tests right
146 # XXX - Temporary hackish testing, we'll move this into proper tests right
147 # away
147 # away
148
148
149 if __name__ == '__main__':
149 if __name__ == '__main__':
150
150
151 # XXX - for now, we need a running cluster to be started separately. The
151 # XXX - for now, we need a running cluster to be started separately. The
152 # daemon work is almost finished, and will make much of this unnecessary.
152 # daemon work is almost finished, and will make much of this unnecessary.
153 from IPython.kernel import client
153 from IPython.kernel import client
154 mec = client.MultiEngineClient(('127.0.0.1',10105))
154 mec = client.MultiEngineClient(('127.0.0.1',10105))
155
155
156 try:
156 try:
157 mec.get_ids()
157 mec.get_ids()
158 except ConnectionRefusedError:
158 except ConnectionRefusedError:
159 import os, time
159 import os, time
160 os.system('ipcluster -n 2 &')
160 os.system('ipcluster -n 2 &')
161 time.sleep(2)
161 time.sleep(2)
162 mec = client.MultiEngineClient(('127.0.0.1',10105))
162 mec = client.MultiEngineClient(('127.0.0.1',10105))
163
163
164 mec.block = False
164 mec.block = False
165
165
166 import itertools
166 import itertools
167 c = itertools.count()
167 c = itertools.count()
168
168
169 parallel = RemoteMultiEngine(mec)
169 parallel = RemoteMultiEngine(mec)
170
170
171 with parallel as pr:
171 with parallel as pr:
172 # A comment
172 # A comment
173 remote() # this means the code below only runs remotely
173 remote() # this means the code below only runs remotely
174 print 'Hello remote world'
174 print 'Hello remote world'
175 x = 3.14
175 x = range(10)
176 # Comments are OK
176 # Comments are OK
177 # Even misindented.
177 # Even misindented.
178 y = x+1
178 y = x+1
179
180
181 with pfor('i',sequence) as pr:
182 print x[i]
183
184 print pr.x + pr.y
1 NO CONTENT: file renamed from IPython/testing/attic/parametric.py to IPython/testing/parametric.py
NO CONTENT: file renamed from IPython/testing/attic/parametric.py to IPython/testing/parametric.py
@@ -1,20 +1,24 b''
1 # Set this prefix to where you want to install the plugin
1 # Set this prefix to where you want to install the plugin
2 PREFIX=~/usr/local
2 PREFIX=~/usr/local
3 PREFIX=~/tmp/local
3 PREFIX=~/tmp/local
4
4
5 plugin: IPython_doctest_plugin.egg-info
5 plugin: IPython_doctest_plugin.egg-info
6
6
7 test: plugin dtexample.py
7 test: plugin dtexample.py
8 nosetests -s --with-ipdoctest --doctest-tests --doctest-extension=txt \
8 nosetests -s --with-ipdoctest --doctest-tests --doctest-extension=txt \
9 dtexample.py test*.txt
9 dtexample.py test*.txt
10
10
11 deb: plugin dtexample.py
11 deb: plugin dtexample.py
12 nosetests -vs --with-ipdoctest --doctest-tests --doctest-extension=txt \
12 nosetests -vs --with-ipdoctest --doctest-tests --doctest-extension=txt \
13 test_combo.txt
13 test_combo.txt
14
14
15 iptest: plugin
16 nosetests -vs --with-ipdoctest --doctest-tests --doctest-extension=txt \
17 IPython
18
15 IPython_doctest_plugin.egg-info: ipdoctest.py setup.py
19 IPython_doctest_plugin.egg-info: ipdoctest.py setup.py
16 python setup.py install --prefix=$(PREFIX)
20 python setup.py install --prefix=$(PREFIX)
17 touch $@
21 touch $@
18
22
19 clean:
23 clean:
20 rm -rf IPython_doctest_plugin.egg-info *~ *pyc build/ dist/
24 rm -rf IPython_doctest_plugin.egg-info *~ *pyc build/ dist/
@@ -1,587 +1,601 b''
1 """Nose Plugin that supports IPython doctests.
1 """Nose Plugin that supports IPython doctests.
2
2
3 Limitations:
3 Limitations:
4
4
5 - When generating examples for use as doctests, make sure that you have
5 - When generating examples for use as doctests, make sure that you have
6 pretty-printing OFF. This can be done either by starting ipython with the
6 pretty-printing OFF. This can be done either by starting ipython with the
7 flag '--nopprint', by setting pprint to 0 in your ipythonrc file, or by
7 flag '--nopprint', by setting pprint to 0 in your ipythonrc file, or by
8 interactively disabling it with %Pprint. This is required so that IPython
8 interactively disabling it with %Pprint. This is required so that IPython
9 output matches that of normal Python, which is used by doctest for internal
9 output matches that of normal Python, which is used by doctest for internal
10 execution.
10 execution.
11
11
12 - Do not rely on specific prompt numbers for results (such as using
12 - Do not rely on specific prompt numbers for results (such as using
13 '_34==True', for example). For IPython tests run via an external process the
13 '_34==True', for example). For IPython tests run via an external process the
14 prompt numbers may be different, and IPython tests run as normal python code
14 prompt numbers may be different, and IPython tests run as normal python code
15 won't even have these special _NN variables set at all.
15 won't even have these special _NN variables set at all.
16
16
17 - IPython functions that produce output as a side-effect of calling a system
17 - IPython functions that produce output as a side-effect of calling a system
18 process (e.g. 'ls') can be doc-tested, but they must be handled in an
18 process (e.g. 'ls') can be doc-tested, but they must be handled in an
19 external IPython process. Such doctests must be tagged with:
19 external IPython process. Such doctests must be tagged with:
20
20
21 # ipdoctest: EXTERNAL
21 # ipdoctest: EXTERNAL
22
22
23 so that the testing machinery handles them differently. Since these are run
23 so that the testing machinery handles them differently. Since these are run
24 via pexpect in an external process, they can't deal with exceptions or other
24 via pexpect in an external process, they can't deal with exceptions or other
25 fancy featurs of regular doctests. You must limit such tests to simple
25 fancy featurs of regular doctests. You must limit such tests to simple
26 matching of the output. For this reason, I recommend you limit these kinds
26 matching of the output. For this reason, I recommend you limit these kinds
27 of doctests to features that truly require a separate process, and use the
27 of doctests to features that truly require a separate process, and use the
28 normal IPython ones (which have all the features of normal doctests) for
28 normal IPython ones (which have all the features of normal doctests) for
29 everything else. See the examples at the bottom of this file for a
29 everything else. See the examples at the bottom of this file for a
30 comparison of what can be done with both types.
30 comparison of what can be done with both types.
31 """
31 """
32
32
33
33
34 #-----------------------------------------------------------------------------
34 #-----------------------------------------------------------------------------
35 # Module imports
35 # Module imports
36
36
37 # From the standard library
37 # From the standard library
38 import __builtin__
38 import __builtin__
39 import commands
39 import commands
40 import doctest
40 import doctest
41 import inspect
41 import inspect
42 import logging
42 import logging
43 import os
43 import os
44 import re
44 import re
45 import sys
45 import sys
46 import unittest
46 import unittest
47
47
48 from inspect import getmodule
48 from inspect import getmodule
49
49
50 # Third-party modules
50 # Third-party modules
51 import nose.core
51 import nose.core
52
52
53 from nose.plugins import doctests, Plugin
53 from nose.plugins import doctests, Plugin
54 from nose.util import anyp, getpackage, test_address, resolve_name, tolist
54 from nose.util import anyp, getpackage, test_address, resolve_name, tolist
55
55
56 # Our own imports
56 # Our own imports
57 #from extdoctest import ExtensionDoctest, DocTestFinder
57 #from extdoctest import ExtensionDoctest, DocTestFinder
58 #from dttools import DocTestFinder, DocTestCase
58 #from dttools import DocTestFinder, DocTestCase
59 #-----------------------------------------------------------------------------
59 #-----------------------------------------------------------------------------
60 # Module globals and other constants
60 # Module globals and other constants
61
61
62 log = logging.getLogger(__name__)
62 log = logging.getLogger(__name__)
63
63
64 ###########################################################################
64 ###########################################################################
65 # *** HACK ***
65 # *** HACK ***
66 # We must start our own ipython object and heavily muck with it so that all the
66 # We must start our own ipython object and heavily muck with it so that all the
67 # modifications IPython makes to system behavior don't send the doctest
67 # modifications IPython makes to system behavior don't send the doctest
68 # machinery into a fit. This code should be considered a gross hack, but it
68 # machinery into a fit. This code should be considered a gross hack, but it
69 # gets the job done.
69 # gets the job done.
70
70
71 def start_ipython():
71 def start_ipython():
72 """Start a global IPython shell, which we need for IPython-specific syntax.
72 """Start a global IPython shell, which we need for IPython-specific syntax.
73 """
73 """
74 import IPython
74 import IPython
75
75
76 def xsys(cmd):
76 def xsys(cmd):
77 """Execute a command and print its output.
77 """Execute a command and print its output.
78
78
79 This is just a convenience function to replace the IPython system call
79 This is just a convenience function to replace the IPython system call
80 with one that is more doctest-friendly.
80 with one that is more doctest-friendly.
81 """
81 """
82 cmd = _ip.IP.var_expand(cmd,depth=1)
82 cmd = _ip.IP.var_expand(cmd,depth=1)
83 sys.stdout.write(commands.getoutput(cmd))
83 sys.stdout.write(commands.getoutput(cmd))
84 sys.stdout.flush()
84 sys.stdout.flush()
85
85
86 # Store certain global objects that IPython modifies
86 # Store certain global objects that IPython modifies
87 _displayhook = sys.displayhook
87 _displayhook = sys.displayhook
88 _excepthook = sys.excepthook
88 _excepthook = sys.excepthook
89 _main = sys.modules.get('__main__')
89 _main = sys.modules.get('__main__')
90
90
91 # Start IPython instance
91 # Start IPython instance
92 IPython.Shell.IPShell(['--classic','--noterm_title'])
92 IPython.Shell.IPShell(['--classic','--noterm_title'])
93
93
94 # Deactivate the various python system hooks added by ipython for
94 # Deactivate the various python system hooks added by ipython for
95 # interactive convenience so we don't confuse the doctest system
95 # interactive convenience so we don't confuse the doctest system
96 sys.modules['__main__'] = _main
96 sys.modules['__main__'] = _main
97 sys.displayhook = _displayhook
97 sys.displayhook = _displayhook
98 sys.excepthook = _excepthook
98 sys.excepthook = _excepthook
99
99
100 # So that ipython magics and aliases can be doctested (they work by making
100 # So that ipython magics and aliases can be doctested (they work by making
101 # a call into a global _ip object)
101 # a call into a global _ip object)
102 _ip = IPython.ipapi.get()
102 _ip = IPython.ipapi.get()
103 __builtin__._ip = _ip
103 __builtin__._ip = _ip
104
104
105 # Modify the IPython system call with one that uses getoutput, so that we
105 # Modify the IPython system call with one that uses getoutput, so that we
106 # can capture subcommands and print them to Python's stdout, otherwise the
106 # can capture subcommands and print them to Python's stdout, otherwise the
107 # doctest machinery would miss them.
107 # doctest machinery would miss them.
108 _ip.system = xsys
108 _ip.system = xsys
109
109
110 # The start call MUST be made here. I'm not sure yet why it doesn't work if
110 # The start call MUST be made here. I'm not sure yet why it doesn't work if
111 # it is made later, at plugin initialization time, but in all my tests, that's
111 # it is made later, at plugin initialization time, but in all my tests, that's
112 # the case.
112 # the case.
113 start_ipython()
113 start_ipython()
114
114
115 # *** END HACK ***
115 # *** END HACK ***
116 ###########################################################################
116 ###########################################################################
117
117
118 #-----------------------------------------------------------------------------
118 #-----------------------------------------------------------------------------
119 # Modified version of the one in the stdlib, that fixes a python bug (doctests
119 # Modified version of the one in the stdlib, that fixes a python bug (doctests
120 # not found in extension modules, http://bugs.python.org/issue3158)
120 # not found in extension modules, http://bugs.python.org/issue3158)
121 class DocTestFinder(doctest.DocTestFinder):
121 class DocTestFinder(doctest.DocTestFinder):
122
122
123 def _from_module(self, module, object):
123 def _from_module(self, module, object):
124 """
124 """
125 Return true if the given object is defined in the given
125 Return true if the given object is defined in the given
126 module.
126 module.
127 """
127 """
128 if module is None:
128 if module is None:
129 #print '_fm C1' # dbg
129 #print '_fm C1' # dbg
130 return True
130 return True
131 elif inspect.isfunction(object):
131 elif inspect.isfunction(object):
132 #print '_fm C2' # dbg
132 #print '_fm C2' # dbg
133 return module.__dict__ is object.func_globals
133 return module.__dict__ is object.func_globals
134 elif inspect.isbuiltin(object):
134 elif inspect.isbuiltin(object):
135 #print '_fm C2-1' # dbg
135 #print '_fm C2-1' # dbg
136 return module.__name__ == object.__module__
136 return module.__name__ == object.__module__
137 elif inspect.isclass(object):
137 elif inspect.isclass(object):
138 #print '_fm C3' # dbg
138 #print '_fm C3' # dbg
139 return module.__name__ == object.__module__
139 return module.__name__ == object.__module__
140 elif inspect.ismethod(object):
140 elif inspect.ismethod(object):
141 # This one may be a bug in cython that fails to correctly set the
141 # This one may be a bug in cython that fails to correctly set the
142 # __module__ attribute of methods, but since the same error is easy
142 # __module__ attribute of methods, but since the same error is easy
143 # to make by extension code writers, having this safety in place
143 # to make by extension code writers, having this safety in place
144 # isn't such a bad idea
144 # isn't such a bad idea
145 #print '_fm C3-1' # dbg
145 #print '_fm C3-1' # dbg
146 return module.__name__ == object.im_class.__module__
146 return module.__name__ == object.im_class.__module__
147 elif inspect.getmodule(object) is not None:
147 elif inspect.getmodule(object) is not None:
148 #print '_fm C4' # dbg
148 #print '_fm C4' # dbg
149 #print 'C4 mod',module,'obj',object # dbg
149 #print 'C4 mod',module,'obj',object # dbg
150 return module is inspect.getmodule(object)
150 return module is inspect.getmodule(object)
151 elif hasattr(object, '__module__'):
151 elif hasattr(object, '__module__'):
152 #print '_fm C5' # dbg
152 #print '_fm C5' # dbg
153 return module.__name__ == object.__module__
153 return module.__name__ == object.__module__
154 elif isinstance(object, property):
154 elif isinstance(object, property):
155 #print '_fm C6' # dbg
155 #print '_fm C6' # dbg
156 return True # [XX] no way not be sure.
156 return True # [XX] no way not be sure.
157 else:
157 else:
158 raise ValueError("object must be a class or function")
158 raise ValueError("object must be a class or function")
159
159
160
160
161
161
162 def _find(self, tests, obj, name, module, source_lines, globs, seen):
162 def _find(self, tests, obj, name, module, source_lines, globs, seen):
163 """
163 """
164 Find tests for the given object and any contained objects, and
164 Find tests for the given object and any contained objects, and
165 add them to `tests`.
165 add them to `tests`.
166 """
166 """
167
167
168 doctest.DocTestFinder._find(self,tests, obj, name, module,
168 doctest.DocTestFinder._find(self,tests, obj, name, module,
169 source_lines, globs, seen)
169 source_lines, globs, seen)
170
170
171 # Below we re-run pieces of the above method with manual modifications,
171 # Below we re-run pieces of the above method with manual modifications,
172 # because the original code is buggy and fails to correctly identify
172 # because the original code is buggy and fails to correctly identify
173 # doctests in extension modules.
173 # doctests in extension modules.
174
174
175 # Local shorthands
175 # Local shorthands
176 from inspect import isroutine, isclass, ismodule
176 from inspect import isroutine, isclass, ismodule
177
177
178 # Look for tests in a module's contained objects.
178 # Look for tests in a module's contained objects.
179 if inspect.ismodule(obj) and self._recurse:
179 if inspect.ismodule(obj) and self._recurse:
180 for valname, val in obj.__dict__.items():
180 for valname, val in obj.__dict__.items():
181 valname1 = '%s.%s' % (name, valname)
181 valname1 = '%s.%s' % (name, valname)
182 if ( (isroutine(val) or isclass(val))
182 if ( (isroutine(val) or isclass(val))
183 and self._from_module(module, val) ):
183 and self._from_module(module, val) ):
184
184
185 self._find(tests, val, valname1, module, source_lines,
185 self._find(tests, val, valname1, module, source_lines,
186 globs, seen)
186 globs, seen)
187
187
188
188
189 # Look for tests in a class's contained objects.
189 # Look for tests in a class's contained objects.
190 if inspect.isclass(obj) and self._recurse:
190 if inspect.isclass(obj) and self._recurse:
191 #print 'RECURSE into class:',obj # dbg
191 #print 'RECURSE into class:',obj # dbg
192 for valname, val in obj.__dict__.items():
192 for valname, val in obj.__dict__.items():
193 #valname1 = '%s.%s' % (name, valname) # dbg
193 #valname1 = '%s.%s' % (name, valname) # dbg
194 #print 'N',name,'VN:',valname,'val:',str(val)[:77] # dbg
194 #print 'N',name,'VN:',valname,'val:',str(val)[:77] # dbg
195 # Special handling for staticmethod/classmethod.
195 # Special handling for staticmethod/classmethod.
196 if isinstance(val, staticmethod):
196 if isinstance(val, staticmethod):
197 val = getattr(obj, valname)
197 val = getattr(obj, valname)
198 if isinstance(val, classmethod):
198 if isinstance(val, classmethod):
199 val = getattr(obj, valname).im_func
199 val = getattr(obj, valname).im_func
200
200
201 # Recurse to methods, properties, and nested classes.
201 # Recurse to methods, properties, and nested classes.
202 if ((inspect.isfunction(val) or inspect.isclass(val) or
202 if ((inspect.isfunction(val) or inspect.isclass(val) or
203 inspect.ismethod(val) or
203 inspect.ismethod(val) or
204 isinstance(val, property)) and
204 isinstance(val, property)) and
205 self._from_module(module, val)):
205 self._from_module(module, val)):
206 valname = '%s.%s' % (name, valname)
206 valname = '%s.%s' % (name, valname)
207 self._find(tests, val, valname, module, source_lines,
207 self._find(tests, val, valname, module, source_lines,
208 globs, seen)
208 globs, seen)
209
209
210
210
211 class DocTestCase(doctests.DocTestCase):
211 class DocTestCase(doctests.DocTestCase):
212 """Proxy for DocTestCase: provides an address() method that
212 """Proxy for DocTestCase: provides an address() method that
213 returns the correct address for the doctest case. Otherwise
213 returns the correct address for the doctest case. Otherwise
214 acts as a proxy to the test case. To provide hints for address(),
214 acts as a proxy to the test case. To provide hints for address(),
215 an obj may also be passed -- this will be used as the test object
215 an obj may also be passed -- this will be used as the test object
216 for purposes of determining the test address, if it is provided.
216 for purposes of determining the test address, if it is provided.
217 """
217 """
218
218
219 # doctests loaded via find(obj) omit the module name
219 # doctests loaded via find(obj) omit the module name
220 # so we need to override id, __repr__ and shortDescription
220 # so we need to override id, __repr__ and shortDescription
221 # bonus: this will squash a 2.3 vs 2.4 incompatiblity
221 # bonus: this will squash a 2.3 vs 2.4 incompatiblity
222 def id(self):
222 def id(self):
223 name = self._dt_test.name
223 name = self._dt_test.name
224 filename = self._dt_test.filename
224 filename = self._dt_test.filename
225 if filename is not None:
225 if filename is not None:
226 pk = getpackage(filename)
226 pk = getpackage(filename)
227 if pk is not None and not name.startswith(pk):
227 if pk is not None and not name.startswith(pk):
228 name = "%s.%s" % (pk, name)
228 name = "%s.%s" % (pk, name)
229 return name
229 return name
230
230
231
231
232 # Classes and functions
232 # Classes and functions
233
233
234 def is_extension_module(filename):
234 def is_extension_module(filename):
235 """Return whether the given filename is an extension module.
235 """Return whether the given filename is an extension module.
236
236
237 This simply checks that the extension is either .so or .pyd.
237 This simply checks that the extension is either .so or .pyd.
238 """
238 """
239 return os.path.splitext(filename)[1].lower() in ('.so','.pyd')
239 return os.path.splitext(filename)[1].lower() in ('.so','.pyd')
240
240
241
241
242 # A simple subclassing of the original with a different class name, so we can
242 # A simple subclassing of the original with a different class name, so we can
243 # distinguish and treat differently IPython examples from pure python ones.
243 # distinguish and treat differently IPython examples from pure python ones.
244 class IPExample(doctest.Example): pass
244 class IPExample(doctest.Example): pass
245
245
246 class IPExternalExample(doctest.Example):
246 class IPExternalExample(doctest.Example):
247 """Doctest examples to be run in an external process."""
247 """Doctest examples to be run in an external process."""
248
248
249 def __init__(self, source, want, exc_msg=None, lineno=0, indent=0,
249 def __init__(self, source, want, exc_msg=None, lineno=0, indent=0,
250 options=None):
250 options=None):
251 # Parent constructor
251 # Parent constructor
252 doctest.Example.__init__(self,source,want,exc_msg,lineno,indent,options)
252 doctest.Example.__init__(self,source,want,exc_msg,lineno,indent,options)
253
253
254 # An EXTRA newline is needed to prevent pexpect hangs
254 # An EXTRA newline is needed to prevent pexpect hangs
255 self.source += '\n'
255 self.source += '\n'
256
256
257 class IPDocTestParser(doctest.DocTestParser):
257 class IPDocTestParser(doctest.DocTestParser):
258 """
258 """
259 A class used to parse strings containing doctest examples.
259 A class used to parse strings containing doctest examples.
260
260
261 Note: This is a version modified to properly recognize IPython input and
261 Note: This is a version modified to properly recognize IPython input and
262 convert any IPython examples into valid Python ones.
262 convert any IPython examples into valid Python ones.
263 """
263 """
264 # This regular expression is used to find doctest examples in a
264 # This regular expression is used to find doctest examples in a
265 # string. It defines three groups: `source` is the source code
265 # string. It defines three groups: `source` is the source code
266 # (including leading indentation and prompts); `indent` is the
266 # (including leading indentation and prompts); `indent` is the
267 # indentation of the first (PS1) line of the source code; and
267 # indentation of the first (PS1) line of the source code; and
268 # `want` is the expected output (including leading indentation).
268 # `want` is the expected output (including leading indentation).
269
269
270 # Classic Python prompts or default IPython ones
270 # Classic Python prompts or default IPython ones
271 _PS1_PY = r'>>>'
271 _PS1_PY = r'>>>'
272 _PS2_PY = r'\.\.\.'
272 _PS2_PY = r'\.\.\.'
273
273
274 _PS1_IP = r'In\ \[\d+\]:'
274 _PS1_IP = r'In\ \[\d+\]:'
275 _PS2_IP = r'\ \ \ \.\.\.+:'
275 _PS2_IP = r'\ \ \ \.\.\.+:'
276
276
277 _RE_TPL = r'''
277 _RE_TPL = r'''
278 # Source consists of a PS1 line followed by zero or more PS2 lines.
278 # Source consists of a PS1 line followed by zero or more PS2 lines.
279 (?P<source>
279 (?P<source>
280 (?:^(?P<indent> [ ]*) (?P<ps1> %s) .*) # PS1 line
280 (?:^(?P<indent> [ ]*) (?P<ps1> %s) .*) # PS1 line
281 (?:\n [ ]* (?P<ps2> %s) .*)*) # PS2 lines
281 (?:\n [ ]* (?P<ps2> %s) .*)*) # PS2 lines
282 \n? # a newline
282 \n? # a newline
283 # Want consists of any non-blank lines that do not start with PS1.
283 # Want consists of any non-blank lines that do not start with PS1.
284 (?P<want> (?:(?![ ]*$) # Not a blank line
284 (?P<want> (?:(?![ ]*$) # Not a blank line
285 (?![ ]*%s) # Not a line starting with PS1
285 (?![ ]*%s) # Not a line starting with PS1
286 (?![ ]*%s) # Not a line starting with PS2
286 (?![ ]*%s) # Not a line starting with PS2
287 .*$\n? # But any other line
287 .*$\n? # But any other line
288 )*)
288 )*)
289 '''
289 '''
290
290
291 _EXAMPLE_RE_PY = re.compile( _RE_TPL % (_PS1_PY,_PS2_PY,_PS1_PY,_PS2_PY),
291 _EXAMPLE_RE_PY = re.compile( _RE_TPL % (_PS1_PY,_PS2_PY,_PS1_PY,_PS2_PY),
292 re.MULTILINE | re.VERBOSE)
292 re.MULTILINE | re.VERBOSE)
293
293
294 _EXAMPLE_RE_IP = re.compile( _RE_TPL % (_PS1_IP,_PS2_IP,_PS1_IP,_PS2_IP),
294 _EXAMPLE_RE_IP = re.compile( _RE_TPL % (_PS1_IP,_PS2_IP,_PS1_IP,_PS2_IP),
295 re.MULTILINE | re.VERBOSE)
295 re.MULTILINE | re.VERBOSE)
296
296
297 def ip2py(self,source):
297 def ip2py(self,source):
298 """Convert input IPython source into valid Python."""
298 """Convert input IPython source into valid Python."""
299 out = []
299 out = []
300 newline = out.append
300 newline = out.append
301 for line in source.splitlines():
301 for lnum,line in enumerate(source.splitlines()):
302 #newline(_ip.IPipython.prefilter(line,True))
302 #newline(_ip.IPipython.prefilter(line,True))
303 newline(_ip.IP.prefilter(line,True))
303 newline(_ip.IP.prefilter(line,lnum>0))
304 newline('') # ensure a closing newline, needed by doctest
304 newline('') # ensure a closing newline, needed by doctest
305 return '\n'.join(out)
305 return '\n'.join(out)
306
306
307 def parse(self, string, name='<string>'):
307 def parse(self, string, name='<string>'):
308 """
308 """
309 Divide the given string into examples and intervening text,
309 Divide the given string into examples and intervening text,
310 and return them as a list of alternating Examples and strings.
310 and return them as a list of alternating Examples and strings.
311 Line numbers for the Examples are 0-based. The optional
311 Line numbers for the Examples are 0-based. The optional
312 argument `name` is a name identifying this string, and is only
312 argument `name` is a name identifying this string, and is only
313 used for error messages.
313 used for error messages.
314 """
314 """
315
315
316 #print 'Parse string:\n',string # dbg
316 #print 'Parse string:\n',string # dbg
317
317
318 string = string.expandtabs()
318 string = string.expandtabs()
319 # If all lines begin with the same indentation, then strip it.
319 # If all lines begin with the same indentation, then strip it.
320 min_indent = self._min_indent(string)
320 min_indent = self._min_indent(string)
321 if min_indent > 0:
321 if min_indent > 0:
322 string = '\n'.join([l[min_indent:] for l in string.split('\n')])
322 string = '\n'.join([l[min_indent:] for l in string.split('\n')])
323
323
324 output = []
324 output = []
325 charno, lineno = 0, 0
325 charno, lineno = 0, 0
326
326
327 # Whether to convert the input from ipython to python syntax
327 # Whether to convert the input from ipython to python syntax
328 ip2py = False
328 ip2py = False
329 # Find all doctest examples in the string. First, try them as Python
329 # Find all doctest examples in the string. First, try them as Python
330 # examples, then as IPython ones
330 # examples, then as IPython ones
331 terms = list(self._EXAMPLE_RE_PY.finditer(string))
331 terms = list(self._EXAMPLE_RE_PY.finditer(string))
332 if terms:
332 if terms:
333 # Normal Python example
333 # Normal Python example
334 #print '-'*70 # dbg
334 #print '-'*70 # dbg
335 #print 'PyExample, Source:\n',string # dbg
335 #print 'PyExample, Source:\n',string # dbg
336 #print '-'*70 # dbg
336 #print '-'*70 # dbg
337 Example = doctest.Example
337 Example = doctest.Example
338 else:
338 else:
339 # It's an ipython example. Note that IPExamples are run
339 # It's an ipython example. Note that IPExamples are run
340 # in-process, so their syntax must be turned into valid python.
340 # in-process, so their syntax must be turned into valid python.
341 # IPExternalExamples are run out-of-process (via pexpect) so they
341 # IPExternalExamples are run out-of-process (via pexpect) so they
342 # don't need any filtering (a real ipython will be executing them).
342 # don't need any filtering (a real ipython will be executing them).
343 terms = list(self._EXAMPLE_RE_IP.finditer(string))
343 terms = list(self._EXAMPLE_RE_IP.finditer(string))
344 if re.search(r'#\s*ipdoctest:\s*EXTERNAL',string):
344 if re.search(r'#\s*ipdoctest:\s*EXTERNAL',string):
345 #print '-'*70 # dbg
345 #print '-'*70 # dbg
346 #print 'IPExternalExample, Source:\n',string # dbg
346 #print 'IPExternalExample, Source:\n',string # dbg
347 #print '-'*70 # dbg
347 #print '-'*70 # dbg
348 Example = IPExternalExample
348 Example = IPExternalExample
349 else:
349 else:
350 #print '-'*70 # dbg
350 #print '-'*70 # dbg
351 #print 'IPExample, Source:\n',string # dbg
351 #print 'IPExample, Source:\n',string # dbg
352 #print '-'*70 # dbg
352 #print '-'*70 # dbg
353 Example = IPExample
353 Example = IPExample
354 ip2py = True
354 ip2py = True
355
355
356 for m in terms:
356 for m in terms:
357 # Add the pre-example text to `output`.
357 # Add the pre-example text to `output`.
358 output.append(string[charno:m.start()])
358 output.append(string[charno:m.start()])
359 # Update lineno (lines before this example)
359 # Update lineno (lines before this example)
360 lineno += string.count('\n', charno, m.start())
360 lineno += string.count('\n', charno, m.start())
361 # Extract info from the regexp match.
361 # Extract info from the regexp match.
362 (source, options, want, exc_msg) = \
362 (source, options, want, exc_msg) = \
363 self._parse_example(m, name, lineno,ip2py)
363 self._parse_example(m, name, lineno,ip2py)
364 if Example is IPExternalExample:
364 if Example is IPExternalExample:
365 options[doctest.NORMALIZE_WHITESPACE] = True
365 options[doctest.NORMALIZE_WHITESPACE] = True
366 want += '\n'
366 want += '\n'
367 # Create an Example, and add it to the list.
367 # Create an Example, and add it to the list.
368 if not self._IS_BLANK_OR_COMMENT(source):
368 if not self._IS_BLANK_OR_COMMENT(source):
369 #print 'Example source:', source # dbg
369 #print 'Example source:', source # dbg
370 output.append(Example(source, want, exc_msg,
370 output.append(Example(source, want, exc_msg,
371 lineno=lineno,
371 lineno=lineno,
372 indent=min_indent+len(m.group('indent')),
372 indent=min_indent+len(m.group('indent')),
373 options=options))
373 options=options))
374 # Update lineno (lines inside this example)
374 # Update lineno (lines inside this example)
375 lineno += string.count('\n', m.start(), m.end())
375 lineno += string.count('\n', m.start(), m.end())
376 # Update charno.
376 # Update charno.
377 charno = m.end()
377 charno = m.end()
378 # Add any remaining post-example text to `output`.
378 # Add any remaining post-example text to `output`.
379 output.append(string[charno:])
379 output.append(string[charno:])
380
380
381 return output
381 return output
382
382
383 def _parse_example(self, m, name, lineno,ip2py=False):
383 def _parse_example(self, m, name, lineno,ip2py=False):
384 """
384 """
385 Given a regular expression match from `_EXAMPLE_RE` (`m`),
385 Given a regular expression match from `_EXAMPLE_RE` (`m`),
386 return a pair `(source, want)`, where `source` is the matched
386 return a pair `(source, want)`, where `source` is the matched
387 example's source code (with prompts and indentation stripped);
387 example's source code (with prompts and indentation stripped);
388 and `want` is the example's expected output (with indentation
388 and `want` is the example's expected output (with indentation
389 stripped).
389 stripped).
390
390
391 `name` is the string's name, and `lineno` is the line number
391 `name` is the string's name, and `lineno` is the line number
392 where the example starts; both are used for error messages.
392 where the example starts; both are used for error messages.
393
393
394 Optional:
394 Optional:
395 `ip2py`: if true, filter the input via IPython to convert the syntax
395 `ip2py`: if true, filter the input via IPython to convert the syntax
396 into valid python.
396 into valid python.
397 """
397 """
398
398
399 # Get the example's indentation level.
399 # Get the example's indentation level.
400 indent = len(m.group('indent'))
400 indent = len(m.group('indent'))
401
401
402 # Divide source into lines; check that they're properly
402 # Divide source into lines; check that they're properly
403 # indented; and then strip their indentation & prompts.
403 # indented; and then strip their indentation & prompts.
404 source_lines = m.group('source').split('\n')
404 source_lines = m.group('source').split('\n')
405
405
406 # We're using variable-length input prompts
406 # We're using variable-length input prompts
407 ps1 = m.group('ps1')
407 ps1 = m.group('ps1')
408 ps2 = m.group('ps2')
408 ps2 = m.group('ps2')
409 ps1_len = len(ps1)
409 ps1_len = len(ps1)
410
410
411 self._check_prompt_blank(source_lines, indent, name, lineno,ps1_len)
411 self._check_prompt_blank(source_lines, indent, name, lineno,ps1_len)
412 if ps2:
412 if ps2:
413 self._check_prefix(source_lines[1:], ' '*indent + ps2, name, lineno)
413 self._check_prefix(source_lines[1:], ' '*indent + ps2, name, lineno)
414
414
415 source = '\n'.join([sl[indent+ps1_len+1:] for sl in source_lines])
415 source = '\n'.join([sl[indent+ps1_len+1:] for sl in source_lines])
416
416
417 if ip2py:
417 if ip2py:
418 # Convert source input from IPython into valid Python syntax
418 # Convert source input from IPython into valid Python syntax
419 source = self.ip2py(source)
419 source = self.ip2py(source)
420
420
421 # Divide want into lines; check that it's properly indented; and
421 # Divide want into lines; check that it's properly indented; and
422 # then strip the indentation. Spaces before the last newline should
422 # then strip the indentation. Spaces before the last newline should
423 # be preserved, so plain rstrip() isn't good enough.
423 # be preserved, so plain rstrip() isn't good enough.
424 want = m.group('want')
424 want = m.group('want')
425 want_lines = want.split('\n')
425 want_lines = want.split('\n')
426 if len(want_lines) > 1 and re.match(r' *$', want_lines[-1]):
426 if len(want_lines) > 1 and re.match(r' *$', want_lines[-1]):
427 del want_lines[-1] # forget final newline & spaces after it
427 del want_lines[-1] # forget final newline & spaces after it
428 self._check_prefix(want_lines, ' '*indent, name,
428 self._check_prefix(want_lines, ' '*indent, name,
429 lineno + len(source_lines))
429 lineno + len(source_lines))
430
430
431 # Remove ipython output prompt that might be present in the first line
431 # Remove ipython output prompt that might be present in the first line
432 want_lines[0] = re.sub(r'Out\[\d+\]: \s*?\n?','',want_lines[0])
432 want_lines[0] = re.sub(r'Out\[\d+\]: \s*?\n?','',want_lines[0])
433
433
434 want = '\n'.join([wl[indent:] for wl in want_lines])
434 want = '\n'.join([wl[indent:] for wl in want_lines])
435
435
436 # If `want` contains a traceback message, then extract it.
436 # If `want` contains a traceback message, then extract it.
437 m = self._EXCEPTION_RE.match(want)
437 m = self._EXCEPTION_RE.match(want)
438 if m:
438 if m:
439 exc_msg = m.group('msg')
439 exc_msg = m.group('msg')
440 else:
440 else:
441 exc_msg = None
441 exc_msg = None
442
442
443 # Extract options from the source.
443 # Extract options from the source.
444 options = self._find_options(source, name, lineno)
444 options = self._find_options(source, name, lineno)
445
445
446 return source, options, want, exc_msg
446 return source, options, want, exc_msg
447
447
448 def _check_prompt_blank(self, lines, indent, name, lineno, ps1_len):
448 def _check_prompt_blank(self, lines, indent, name, lineno, ps1_len):
449 """
449 """
450 Given the lines of a source string (including prompts and
450 Given the lines of a source string (including prompts and
451 leading indentation), check to make sure that every prompt is
451 leading indentation), check to make sure that every prompt is
452 followed by a space character. If any line is not followed by
452 followed by a space character. If any line is not followed by
453 a space character, then raise ValueError.
453 a space character, then raise ValueError.
454
454
455 Note: IPython-modified version which takes the input prompt length as a
455 Note: IPython-modified version which takes the input prompt length as a
456 parameter, so that prompts of variable length can be dealt with.
456 parameter, so that prompts of variable length can be dealt with.
457 """
457 """
458 space_idx = indent+ps1_len
458 space_idx = indent+ps1_len
459 min_len = space_idx+1
459 min_len = space_idx+1
460 for i, line in enumerate(lines):
460 for i, line in enumerate(lines):
461 if len(line) >= min_len and line[space_idx] != ' ':
461 if len(line) >= min_len and line[space_idx] != ' ':
462 raise ValueError('line %r of the docstring for %s '
462 raise ValueError('line %r of the docstring for %s '
463 'lacks blank after %s: %r' %
463 'lacks blank after %s: %r' %
464 (lineno+i+1, name,
464 (lineno+i+1, name,
465 line[indent:space_idx], line))
465 line[indent:space_idx], line))
466
466
467 SKIP = doctest.register_optionflag('SKIP')
467 SKIP = doctest.register_optionflag('SKIP')
468
468
469 ###########################################################################
469 ###########################################################################
470
470
471 class DocFileCase(doctest.DocFileCase):
471 class DocFileCase(doctest.DocFileCase):
472 """Overrides to provide filename
472 """Overrides to provide filename
473 """
473 """
474 def address(self):
474 def address(self):
475 return (self._dt_test.filename, None, None)
475 return (self._dt_test.filename, None, None)
476
476
477
477
478 class ExtensionDoctest(doctests.Doctest):
478 class ExtensionDoctest(doctests.Doctest):
479 """Nose Plugin that supports doctests in extension modules.
479 """Nose Plugin that supports doctests in extension modules.
480 """
480 """
481 name = 'extdoctest' # call nosetests with --with-extdoctest
481 name = 'extdoctest' # call nosetests with --with-extdoctest
482 enabled = True
482 enabled = True
483
483
484 def options(self, parser, env=os.environ):
484 def options(self, parser, env=os.environ):
485 Plugin.options(self, parser, env)
485 Plugin.options(self, parser, env)
486
486
487 def configure(self, options, config):
487 def configure(self, options, config):
488 Plugin.configure(self, options, config)
488 Plugin.configure(self, options, config)
489 self.doctest_tests = options.doctest_tests
489 self.doctest_tests = options.doctest_tests
490 self.extension = tolist(options.doctestExtension)
490 self.extension = tolist(options.doctestExtension)
491 self.finder = DocTestFinder()
491 self.finder = DocTestFinder()
492 self.parser = doctest.DocTestParser()
492 self.parser = doctest.DocTestParser()
493
493
494
494
495 def loadTestsFromExtensionModule(self,filename):
495 def loadTestsFromExtensionModule(self,filename):
496 bpath,mod = os.path.split(filename)
496 bpath,mod = os.path.split(filename)
497 modname = os.path.splitext(mod)[0]
497 modname = os.path.splitext(mod)[0]
498 try:
498 try:
499 sys.path.append(bpath)
499 sys.path.append(bpath)
500 module = __import__(modname)
500 module = __import__(modname)
501 tests = list(self.loadTestsFromModule(module))
501 tests = list(self.loadTestsFromModule(module))
502 finally:
502 finally:
503 sys.path.pop()
503 sys.path.pop()
504 return tests
504 return tests
505
505
506 def loadTestsFromFile(self, filename):
506 def loadTestsFromFile(self, filename):
507 if is_extension_module(filename):
507 if is_extension_module(filename):
508 for t in self.loadTestsFromExtensionModule(filename):
508 for t in self.loadTestsFromExtensionModule(filename):
509 yield t
509 yield t
510 else:
510 else:
511 ## for t in list(doctests.Doctest.loadTestsFromFile(self,filename)):
511 ## for t in list(doctests.Doctest.loadTestsFromFile(self,filename)):
512 ## yield t
512 ## yield t
513 pass
513 pass
514
514
515 if self.extension and anyp(filename.endswith, self.extension):
515 if self.extension and anyp(filename.endswith, self.extension):
516 #print 'lTF',filename # dbg
516 #print 'lTF',filename # dbg
517 name = os.path.basename(filename)
517 name = os.path.basename(filename)
518 dh = open(filename)
518 dh = open(filename)
519 try:
519 try:
520 doc = dh.read()
520 doc = dh.read()
521 finally:
521 finally:
522 dh.close()
522 dh.close()
523 test = self.parser.get_doctest(
523 test = self.parser.get_doctest(
524 doc, globs={'__file__': filename}, name=name,
524 doc, globs={'__file__': filename}, name=name,
525 filename=filename, lineno=0)
525 filename=filename, lineno=0)
526 if test.examples:
526 if test.examples:
527 #print 'FileCase:',test.examples # dbg
527 #print 'FileCase:',test.examples # dbg
528 yield DocFileCase(test)
528 yield DocFileCase(test)
529 else:
529 else:
530 yield False # no tests to load
530 yield False # no tests to load
531
531
532
532
533 def wantFile(self,filename):
533 def wantFile(self,filename):
534 """Return whether the given filename should be scanned for tests.
534 """Return whether the given filename should be scanned for tests.
535
535
536 Modified version that accepts extension modules as valid containers for
536 Modified version that accepts extension modules as valid containers for
537 doctests.
537 doctests.
538 """
538 """
539 #print 'Filename:',filename # dbg
539 #print 'Filename:',filename # dbg
540
540
541 # temporarily hardcoded list, will move to driver later
542 exclude = ['IPython/external/',
543 'IPython/Extensions/ipy_',
544 'IPython/platutils_win32',
545 'IPython/frontend/cocoa',
546 'IPython_doctest_plugin',
547 'IPython/Gnuplot',
548 'IPython/Extensions/PhysicalQIn']
549
550 for fex in exclude:
551 if fex in filename: # substring
552 #print '###>>> SKIP:',filename # dbg
553 return False
554
541 if is_extension_module(filename):
555 if is_extension_module(filename):
542 return True
556 return True
543 else:
557 else:
544 return doctests.Doctest.wantFile(self,filename)
558 return doctests.Doctest.wantFile(self,filename)
545
559
546 # NOTE: the method below is a *copy* of the one in the nose doctests
560 # NOTE: the method below is a *copy* of the one in the nose doctests
547 # plugin, but we have to replicate it here in order to have it resolve the
561 # plugin, but we have to replicate it here in order to have it resolve the
548 # DocTestCase (last line) to our local copy, since the nose plugin doesn't
562 # DocTestCase (last line) to our local copy, since the nose plugin doesn't
549 # provide a public hook for what TestCase class to use. The alternative
563 # provide a public hook for what TestCase class to use. The alternative
550 # would be to monkeypatch doctest in the stdlib, but that's ugly and
564 # would be to monkeypatch doctest in the stdlib, but that's ugly and
551 # brittle, since a change in plugin load order can break it. So for now,
565 # brittle, since a change in plugin load order can break it. So for now,
552 # we just paste this in here, inelegant as this may be.
566 # we just paste this in here, inelegant as this may be.
553
567
554 def loadTestsFromModule(self, module):
568 def loadTestsFromModule(self, module):
555 #print 'lTM',module # dbg
569 #print 'lTM',module # dbg
556
570
557 if not self.matches(module.__name__):
571 if not self.matches(module.__name__):
558 log.debug("Doctest doesn't want module %s", module)
572 log.debug("Doctest doesn't want module %s", module)
559 return
573 return
560 tests = self.finder.find(module)
574 tests = self.finder.find(module)
561 if not tests:
575 if not tests:
562 return
576 return
563 tests.sort()
577 tests.sort()
564 module_file = module.__file__
578 module_file = module.__file__
565 if module_file[-4:] in ('.pyc', '.pyo'):
579 if module_file[-4:] in ('.pyc', '.pyo'):
566 module_file = module_file[:-1]
580 module_file = module_file[:-1]
567 for test in tests:
581 for test in tests:
568 if not test.examples:
582 if not test.examples:
569 continue
583 continue
570 if not test.filename:
584 if not test.filename:
571 test.filename = module_file
585 test.filename = module_file
572 yield DocTestCase(test)
586 yield DocTestCase(test)
573
587
574 class IPythonDoctest(ExtensionDoctest):
588 class IPythonDoctest(ExtensionDoctest):
575 """Nose Plugin that supports doctests in extension modules.
589 """Nose Plugin that supports doctests in extension modules.
576 """
590 """
577 name = 'ipdoctest' # call nosetests with --with-ipdoctest
591 name = 'ipdoctest' # call nosetests with --with-ipdoctest
578 enabled = True
592 enabled = True
579
593
580 def configure(self, options, config):
594 def configure(self, options, config):
581
595
582 Plugin.configure(self, options, config)
596 Plugin.configure(self, options, config)
583 self.doctest_tests = options.doctest_tests
597 self.doctest_tests = options.doctest_tests
584 self.extension = tolist(options.doctestExtension)
598 self.extension = tolist(options.doctestExtension)
585 self.parser = IPDocTestParser()
599 self.parser = IPDocTestParser()
586 #self.finder = DocTestFinder(parser=IPDocTestParser())
600 #self.finder = DocTestFinder(parser=IPDocTestParser())
587 self.finder = DocTestFinder(parser=self.parser)
601 self.finder = DocTestFinder(parser=self.parser)
General Comments 0
You need to be logged in to leave comments. Login now