##// END OF EJS Templates
Use "::" to get proper literal blocks in the docstrings....
walter.doerwald -
Show More
@@ -1,2252 +1,2264 b''
1 # -*- coding: iso-8859-1 -*-
1 # -*- coding: iso-8859-1 -*-
2
2
3 """
3 """
4 ``ipipe`` provides classes to be used in an interactive Python session. Doing a
4 ``ipipe`` provides classes to be used in an interactive Python session. Doing a
5 ``from ipipe import *`` is the preferred way to do this. The name of all
5 ``from ipipe import *`` is the preferred way to do this. The name of all
6 objects imported this way starts with ``i`` to minimize collisions.
6 objects imported this way starts with ``i`` to minimize collisions.
7
7
8 ``ipipe`` supports "pipeline expressions", which is something resembling Unix
8 ``ipipe`` supports "pipeline expressions", which is something resembling Unix
9 pipes. An example is:
9 pipes. An example is::
10
10
11 >>> ienv | isort("key.lower()")
11 >>> ienv | isort("key.lower()")
12
12
13 This gives a listing of all environment variables sorted by name.
13 This gives a listing of all environment variables sorted by name.
14
14
15
15
16 There are three types of objects in a pipeline expression:
16 There are three types of objects in a pipeline expression:
17
17
18 * ``Table``s: These objects produce items. Examples are ``ils`` (listing the
18 * ``Table``s: These objects produce items. Examples are ``ils`` (listing the
19 current directory, ``ienv`` (listing environment variables), ``ipwd`` (listing
19 current directory, ``ienv`` (listing environment variables), ``ipwd`` (listing
20 user accounts) and ``igrp`` (listing user groups). A ``Table`` must be the
20 user accounts) and ``igrp`` (listing user groups). A ``Table`` must be the
21 first object in a pipe expression.
21 first object in a pipe expression.
22
22
23 * ``Pipe``s: These objects sit in the middle of a pipe expression. They
23 * ``Pipe``s: These objects sit in the middle of a pipe expression. They
24 transform the input in some way (e.g. filtering or sorting it). Examples are:
24 transform the input in some way (e.g. filtering or sorting it). Examples are:
25 ``ifilter`` (which filters the input pipe), ``isort`` (which sorts the input
25 ``ifilter`` (which filters the input pipe), ``isort`` (which sorts the input
26 pipe) and ``ieval`` (which evaluates a function or expression for each object
26 pipe) and ``ieval`` (which evaluates a function or expression for each object
27 in the input pipe).
27 in the input pipe).
28
28
29 * ``Display``s: These objects can be put as the last object in a pipeline
29 * ``Display``s: These objects can be put as the last object in a pipeline
30 expression. There are responsible for displaying the result of the pipeline
30 expression. There are responsible for displaying the result of the pipeline
31 expression. If a pipeline expression doesn't end in a display object a default
31 expression. If a pipeline expression doesn't end in a display object a default
32 display objects will be used. One example is ``ibrowse`` which is a ``curses``
32 display objects will be used. One example is ``ibrowse`` which is a ``curses``
33 based browser.
33 based browser.
34
34
35
35
36 Adding support for pipeline expressions to your own objects can be done through
36 Adding support for pipeline expressions to your own objects can be done through
37 three extensions points (all of them optional):
37 three extensions points (all of them optional):
38
38
39 * An object that will be displayed as a row by a ``Display`` object should
39 * An object that will be displayed as a row by a ``Display`` object should
40 implement the method ``__xattrs__(self, mode)`` method or register an
40 implement the method ``__xattrs__(self, mode)`` method or register an
41 implementation of the generic function ``xattrs``. For more info see ``xattrs``.
41 implementation of the generic function ``xattrs``. For more info see ``xattrs``.
42
42
43 * When an object ``foo`` is displayed by a ``Display`` object, the generic
43 * When an object ``foo`` is displayed by a ``Display`` object, the generic
44 function ``xrepr`` is used.
44 function ``xrepr`` is used.
45
45
46 * Objects that can be iterated by ``Pipe``s must iterable. For special cases,
46 * Objects that can be iterated by ``Pipe``s must iterable. For special cases,
47 where iteration for display is different than the normal iteration a special
47 where iteration for display is different than the normal iteration a special
48 implementation can be registered with the generic function ``xiter``. This makes
48 implementation can be registered with the generic function ``xiter``. This
49 it possible to use dictionaries and modules in pipeline expressions, for example:
49 makes it possible to use dictionaries and modules in pipeline expressions,
50 for example::
50
51
51 >>> import sys
52 >>> import sys
52 >>> sys | ifilter("isinstance(value, int)") | idump
53 >>> sys | ifilter("isinstance(value, int)") | idump
53 key |value
54 key |value
54 api_version| 1012
55 api_version| 1012
55 dllhandle | 503316480
56 dllhandle | 503316480
56 hexversion | 33817328
57 hexversion | 33817328
57 maxint |2147483647
58 maxint |2147483647
58 maxunicode | 65535
59 maxunicode | 65535
59 >>> sys.modules | ifilter("_.value is not None") | isort("_.key.lower()")
60 >>> sys.modules | ifilter("_.value is not None") | isort("_.key.lower()")
60 ...
61 ...
61
62
62 Note: The expression strings passed to ``ifilter()`` and ``isort()`` can
63 Note: The expression strings passed to ``ifilter()`` and ``isort()`` can
63 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
64 of the attributes of the object, i.e.:
65 of the attributes of the object, i.e.::
65
66
66 >>> sys.modules | ifilter("_.value is not None") | isort("_.key.lower()")
67 >>> sys.modules | ifilter("_.value is not None") | isort("_.key.lower()")
67
68
68 does the same as
69 does the same as::
69
70
70 >>> sys.modules | ifilter("value is not None") | isort("key.lower()")
71 >>> sys.modules | ifilter("value is not None") | isort("key.lower()")
71
72
72 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
73 the object as an argument) to ``ifilter()``, ``isort()`` and ``ieval()``:
74 the object as an argument) to ``ifilter()``, ``isort()`` and ``ieval()``::
74
75
75 >>> sys | ifilter(lambda _:isinstance(_.value, int)) \
76 >>> sys | ifilter(lambda _:isinstance(_.value, int)) \
76 ... | ieval(lambda _: (_.key, hex(_.value))) | idump
77 ... | ieval(lambda _: (_.key, hex(_.value))) | idump
77 0 |1
78 0 |1
78 api_version|0x3f4
79 api_version|0x3f4
79 dllhandle |0x1e000000
80 dllhandle |0x1e000000
80 hexversion |0x20402f0
81 hexversion |0x20402f0
81 maxint |0x7fffffff
82 maxint |0x7fffffff
82 maxunicode |0xffff
83 maxunicode |0xffff
83 """
84 """
84
85
85 import sys, os, os.path, stat, glob, new, csv, datetime, types
86 import sys, os, os.path, stat, glob, new, csv, datetime, types
86 import itertools, mimetypes, StringIO
87 import itertools, mimetypes, StringIO
87
88
88 try: # Python 2.3 compatibility
89 try: # Python 2.3 compatibility
89 import collections
90 import collections
90 except ImportError:
91 except ImportError:
91 deque = list
92 deque = list
92 else:
93 else:
93 deque = collections.deque
94 deque = collections.deque
94
95
95 try: # Python 2.3 compatibility
96 try: # Python 2.3 compatibility
96 set
97 set
97 except NameError:
98 except NameError:
98 import sets
99 import sets
99 set = sets.Set
100 set = sets.Set
100
101
101 try: # Python 2.3 compatibility
102 try: # Python 2.3 compatibility
102 sorted
103 sorted
103 except NameError:
104 except NameError:
104 def sorted(iterator, key=None, reverse=False):
105 def sorted(iterator, key=None, reverse=False):
105 items = list(iterator)
106 items = list(iterator)
106 if key is not None:
107 if key is not None:
107 items.sort(lambda i1, i2: cmp(key(i1), key(i2)))
108 items.sort(lambda i1, i2: cmp(key(i1), key(i2)))
108 else:
109 else:
109 items.sort()
110 items.sort()
110 if reverse:
111 if reverse:
111 items.reverse()
112 items.reverse()
112 return items
113 return items
113
114
114 try:
115 try:
115 import pwd
116 import pwd
116 except ImportError:
117 except ImportError:
117 pwd = None
118 pwd = None
118
119
119 try:
120 try:
120 import grp
121 import grp
121 except ImportError:
122 except ImportError:
122 grp = None
123 grp = None
123
124
124 from IPython.external import simplegeneric
125 from IPython.external import simplegeneric
125
126
126 import path
127 import path
127
128
128 try:
129 try:
129 from IPython import genutils, generics
130 from IPython import genutils, generics
130 except ImportError:
131 except ImportError:
131 genutils = None
132 genutils = None
132 generics = None
133 generics = None
133
134
134 from IPython import ipapi
135 from IPython import ipapi
135
136
136
137
137 __all__ = [
138 __all__ = [
138 "ifile", "ils", "iglob", "iwalk", "ipwdentry", "ipwd", "igrpentry", "igrp",
139 "ifile", "ils", "iglob", "iwalk", "ipwdentry", "ipwd", "igrpentry", "igrp",
139 "icsv", "ix", "ichain", "isort", "ifilter", "ieval", "ienum",
140 "icsv", "ix", "ichain", "isort", "ifilter", "ieval", "ienum",
140 "ienv", "ihist", "icap", "idump", "iless"
141 "ienv", "ihist", "icap", "idump", "iless"
141 ]
142 ]
142
143
143
144
144 os.stat_float_times(True) # enable microseconds
145 os.stat_float_times(True) # enable microseconds
145
146
146
147
147 class AttrNamespace(object):
148 class AttrNamespace(object):
148 """
149 """
149 Helper class that is used for providing a namespace for evaluating
150 Helper class that is used for providing a namespace for evaluating
150 expressions containing attribute names of an object.
151 expressions containing attribute names of an object.
151 """
152 """
152 def __init__(self, wrapped):
153 def __init__(self, wrapped):
153 self.wrapped = wrapped
154 self.wrapped = wrapped
154
155
155 def __getitem__(self, name):
156 def __getitem__(self, name):
156 if name == "_":
157 if name == "_":
157 return self.wrapped
158 return self.wrapped
158 try:
159 try:
159 return getattr(self.wrapped, name)
160 return getattr(self.wrapped, name)
160 except AttributeError:
161 except AttributeError:
161 raise KeyError(name)
162 raise KeyError(name)
162
163
163 # Python 2.3 compatibility
164 # Python 2.3 compatibility
164 # use eval workaround to find out which names are used in the
165 # use eval workaround to find out which names are used in the
165 # eval string and put them into the locals. This works for most
166 # eval string and put them into the locals. This works for most
166 # normal uses case, bizarre ones like accessing the locals()
167 # normal uses case, bizarre ones like accessing the locals()
167 # will fail
168 # will fail
168 try:
169 try:
169 eval("_", None, AttrNamespace(None))
170 eval("_", None, AttrNamespace(None))
170 except TypeError:
171 except TypeError:
171 real_eval = eval
172 real_eval = eval
172 def eval(codestring, _globals, _locals):
173 def eval(codestring, _globals, _locals):
173 """
174 """
174 eval(source[, globals[, locals]]) -> value
175 eval(source[, globals[, locals]]) -> value
175
176
176 Evaluate the source in the context of globals and locals.
177 Evaluate the source in the context of globals and locals.
177 The source may be a string representing a Python expression
178 The source may be a string representing a Python expression
178 or a code object as returned by compile().
179 or a code object as returned by compile().
179 The globals must be a dictionary and locals can be any mappping.
180 The globals must be a dictionary and locals can be any mappping.
180
181
181 This function is a workaround for the shortcomings of
182 This function is a workaround for the shortcomings of
182 Python 2.3's eval.
183 Python 2.3's eval.
183 """
184 """
184
185
185 if isinstance(codestring, basestring):
186 if isinstance(codestring, basestring):
186 code = compile(codestring, "_eval", "eval")
187 code = compile(codestring, "_eval", "eval")
187 else:
188 else:
188 code = codestring
189 code = codestring
189 newlocals = {}
190 newlocals = {}
190 for name in code.co_names:
191 for name in code.co_names:
191 try:
192 try:
192 newlocals[name] = _locals[name]
193 newlocals[name] = _locals[name]
193 except KeyError:
194 except KeyError:
194 pass
195 pass
195 return real_eval(code, _globals, newlocals)
196 return real_eval(code, _globals, newlocals)
196
197
197
198
198 noitem = object()
199 noitem = object()
199
200
200
201
201 def item(iterator, index, default=noitem):
202 def item(iterator, index, default=noitem):
202 """
203 """
203 Return the ``index``th item from the iterator ``iterator``.
204 Return the ``index``th item from the iterator ``iterator``.
204 ``index`` must be an integer (negative integers are relative to the
205 ``index`` must be an integer (negative integers are relative to the
205 end (i.e. the last items produced by the iterator)).
206 end (i.e. the last items produced by the iterator)).
206
207
207 If ``default`` is given, this will be the default value when
208 If ``default`` is given, this will be the default value when
208 the iterator doesn't contain an item at this position. Otherwise an
209 the iterator doesn't contain an item at this position. Otherwise an
209 ``IndexError`` will be raised.
210 ``IndexError`` will be raised.
210
211
211 Note that using this function will partially or totally exhaust the
212 Note that using this function will partially or totally exhaust the
212 iterator.
213 iterator.
213 """
214 """
214 i = index
215 i = index
215 if i>=0:
216 if i>=0:
216 for item in iterator:
217 for item in iterator:
217 if not i:
218 if not i:
218 return item
219 return item
219 i -= 1
220 i -= 1
220 else:
221 else:
221 i = -index
222 i = -index
222 cache = deque()
223 cache = deque()
223 for item in iterator:
224 for item in iterator:
224 cache.append(item)
225 cache.append(item)
225 if len(cache)>i:
226 if len(cache)>i:
226 cache.popleft()
227 cache.popleft()
227 if len(cache)==i:
228 if len(cache)==i:
228 return cache.popleft()
229 return cache.popleft()
229 if default is noitem:
230 if default is noitem:
230 raise IndexError(index)
231 raise IndexError(index)
231 else:
232 else:
232 return default
233 return default
233
234
234
235
235 def getglobals(g):
236 def getglobals(g):
236 """
237 """
237 Return the global namespace that is used for expression strings in
238 Return the global namespace that is used for expression strings in
238 ``ifilter`` and others. This is ``g`` or (if ``g`` is ``None``) IPython's
239 ``ifilter`` and others. This is ``g`` or (if ``g`` is ``None``) IPython's
239 user namespace.
240 user namespace.
240 """
241 """
241 if g is None:
242 if g is None:
242 if ipapi is not None:
243 if ipapi is not None:
243 api = ipapi.get()
244 api = ipapi.get()
244 if api is not None:
245 if api is not None:
245 return api.user_ns
246 return api.user_ns
246 return globals()
247 return globals()
247 return g
248 return g
248
249
249
250
250 class Descriptor(object):
251 class Descriptor(object):
251 """
252 """
252 A ``Descriptor`` object is used for describing the attributes of objects.
253 A ``Descriptor`` object is used for describing the attributes of objects.
253 """
254 """
254 def __hash__(self):
255 def __hash__(self):
255 return hash(self.__class__) ^ hash(self.key())
256 return hash(self.__class__) ^ hash(self.key())
256
257
257 def __eq__(self, other):
258 def __eq__(self, other):
258 return self.__class__ is other.__class__ and self.key() == other.key()
259 return self.__class__ is other.__class__ and self.key() == other.key()
259
260
260 def __ne__(self, other):
261 def __ne__(self, other):
261 return self.__class__ is not other.__class__ or self.key() != other.key()
262 return self.__class__ is not other.__class__ or self.key() != other.key()
262
263
263 def key(self):
264 def key(self):
264 pass
265 pass
265
266
266 def name(self):
267 def name(self):
267 """
268 """
268 Return the name of this attribute for display by a ``Display`` object
269 Return the name of this attribute for display by a ``Display`` object
269 (e.g. as a column title).
270 (e.g. as a column title).
270 """
271 """
271 key = self.key()
272 key = self.key()
272 if key is None:
273 if key is None:
273 return "_"
274 return "_"
274 return str(key)
275 return str(key)
275
276
276 def attrtype(self, obj):
277 def attrtype(self, obj):
277 """
278 """
278 Return the type of this attribute (i.e. something like "attribute" or
279 Return the type of this attribute (i.e. something like "attribute" or
279 "method").
280 "method").
280 """
281 """
281
282
282 def valuetype(self, obj):
283 def valuetype(self, obj):
283 """
284 """
284 Return the type of this attribute value of the object ``obj``.
285 Return the type of this attribute value of the object ``obj``.
285 """
286 """
286
287
287 def value(self, obj):
288 def value(self, obj):
288 """
289 """
289 Return the value of this attribute of the object ``obj``.
290 Return the value of this attribute of the object ``obj``.
290 """
291 """
291
292
292 def doc(self, obj):
293 def doc(self, obj):
293 """
294 """
294 Return the documentation for this attribute.
295 Return the documentation for this attribute.
295 """
296 """
296
297
297 def shortdoc(self, obj):
298 def shortdoc(self, obj):
298 """
299 """
299 Return a short documentation for this attribute (defaulting to the
300 Return a short documentation for this attribute (defaulting to the
300 first line).
301 first line).
301 """
302 """
302 doc = self.doc(obj)
303 doc = self.doc(obj)
303 if doc is not None:
304 if doc is not None:
304 doc = doc.strip().splitlines()[0].strip()
305 doc = doc.strip().splitlines()[0].strip()
305 return doc
306 return doc
306
307
307 def iter(self, obj):
308 def iter(self, obj):
308 """
309 """
309 Return an iterator for this attribute of the object ``obj``.
310 Return an iterator for this attribute of the object ``obj``.
310 """
311 """
311 return xiter(self.value(obj))
312 return xiter(self.value(obj))
312
313
313
314
314 class SelfDescriptor(Descriptor):
315 class SelfDescriptor(Descriptor):
315 """
316 """
316 A ``SelfDescriptor`` describes the object itself.
317 A ``SelfDescriptor`` describes the object itself.
317 """
318 """
318 def key(self):
319 def key(self):
319 return None
320 return None
320
321
321 def attrtype(self, obj):
322 def attrtype(self, obj):
322 return "self"
323 return "self"
323
324
324 def valuetype(self, obj):
325 def valuetype(self, obj):
325 return type(obj)
326 return type(obj)
326
327
327 def value(self, obj):
328 def value(self, obj):
328 return obj
329 return obj
329
330
330 def __repr__(self):
331 def __repr__(self):
331 return "Self"
332 return "Self"
332
333
333 selfdescriptor = SelfDescriptor() # there's no need for more than one
334 selfdescriptor = SelfDescriptor() # there's no need for more than one
334
335
335
336
336 class AttributeDescriptor(Descriptor):
337 class AttributeDescriptor(Descriptor):
337 """
338 """
338 An ``AttributeDescriptor`` describes a simple attribute of an object.
339 An ``AttributeDescriptor`` describes a simple attribute of an object.
339 """
340 """
340 __slots__ = ("_name", "_doc")
341 __slots__ = ("_name", "_doc")
341
342
342 def __init__(self, name, doc=None):
343 def __init__(self, name, doc=None):
343 self._name = name
344 self._name = name
344 self._doc = doc
345 self._doc = doc
345
346
346 def key(self):
347 def key(self):
347 return self._name
348 return self._name
348
349
349 def doc(self, obj):
350 def doc(self, obj):
350 return self._doc
351 return self._doc
351
352
352 def attrtype(self, obj):
353 def attrtype(self, obj):
353 return "attr"
354 return "attr"
354
355
355 def valuetype(self, obj):
356 def valuetype(self, obj):
356 return type(getattr(obj, self._name))
357 return type(getattr(obj, self._name))
357
358
358 def value(self, obj):
359 def value(self, obj):
359 return getattr(obj, self._name)
360 return getattr(obj, self._name)
360
361
361 def __repr__(self):
362 def __repr__(self):
362 if self._doc is None:
363 if self._doc is None:
363 return "Attribute(%r)" % self._name
364 return "Attribute(%r)" % self._name
364 else:
365 else:
365 return "Attribute(%r, %r)" % (self._name, self._doc)
366 return "Attribute(%r, %r)" % (self._name, self._doc)
366
367
367
368
368 class IndexDescriptor(Descriptor):
369 class IndexDescriptor(Descriptor):
369 """
370 """
370 An ``IndexDescriptor`` describes an "attribute" of an object that is fetched
371 An ``IndexDescriptor`` describes an "attribute" of an object that is fetched
371 via ``__getitem__``.
372 via ``__getitem__``.
372 """
373 """
373 __slots__ = ("_index",)
374 __slots__ = ("_index",)
374
375
375 def __init__(self, index):
376 def __init__(self, index):
376 self._index = index
377 self._index = index
377
378
378 def key(self):
379 def key(self):
379 return self._index
380 return self._index
380
381
381 def attrtype(self, obj):
382 def attrtype(self, obj):
382 return "item"
383 return "item"
383
384
384 def valuetype(self, obj):
385 def valuetype(self, obj):
385 return type(obj[self._index])
386 return type(obj[self._index])
386
387
387 def value(self, obj):
388 def value(self, obj):
388 return obj[self._index]
389 return obj[self._index]
389
390
390 def __repr__(self):
391 def __repr__(self):
391 return "Index(%r)" % self._index
392 return "Index(%r)" % self._index
392
393
393
394
394 class MethodDescriptor(Descriptor):
395 class MethodDescriptor(Descriptor):
395 """
396 """
396 A ``MethodDescriptor`` describes a method of an object that can be called
397 A ``MethodDescriptor`` describes a method of an object that can be called
397 without argument. Note that this method shouldn't change the object.
398 without argument. Note that this method shouldn't change the object.
398 """
399 """
399 __slots__ = ("_name", "_doc")
400 __slots__ = ("_name", "_doc")
400
401
401 def __init__(self, name, doc=None):
402 def __init__(self, name, doc=None):
402 self._name = name
403 self._name = name
403 self._doc = doc
404 self._doc = doc
404
405
405 def key(self):
406 def key(self):
406 return self._name
407 return self._name
407
408
408 def doc(self, obj):
409 def doc(self, obj):
409 if self._doc is None:
410 if self._doc is None:
410 return getattr(obj, self._name).__doc__
411 return getattr(obj, self._name).__doc__
411 return self._doc
412 return self._doc
412
413
413 def attrtype(self, obj):
414 def attrtype(self, obj):
414 return "method"
415 return "method"
415
416
416 def valuetype(self, obj):
417 def valuetype(self, obj):
417 return type(self.value(obj))
418 return type(self.value(obj))
418
419
419 def value(self, obj):
420 def value(self, obj):
420 return getattr(obj, self._name)()
421 return getattr(obj, self._name)()
421
422
422 def __repr__(self):
423 def __repr__(self):
423 if self._doc is None:
424 if self._doc is None:
424 return "Method(%r)" % self._name
425 return "Method(%r)" % self._name
425 else:
426 else:
426 return "Method(%r, %r)" % (self._name, self._doc)
427 return "Method(%r, %r)" % (self._name, self._doc)
427
428
428
429
429 class IterAttributeDescriptor(Descriptor):
430 class IterAttributeDescriptor(Descriptor):
430 """
431 """
431 An ``IterAttributeDescriptor`` works like an ``AttributeDescriptor`` but
432 An ``IterAttributeDescriptor`` works like an ``AttributeDescriptor`` but
432 doesn't return an attribute values (because this value might be e.g. a large
433 doesn't return an attribute values (because this value might be e.g. a large
433 list).
434 list).
434 """
435 """
435 __slots__ = ("_name", "_doc")
436 __slots__ = ("_name", "_doc")
436
437
437 def __init__(self, name, doc=None):
438 def __init__(self, name, doc=None):
438 self._name = name
439 self._name = name
439 self._doc = doc
440 self._doc = doc
440
441
441 def key(self):
442 def key(self):
442 return self._name
443 return self._name
443
444
444 def doc(self, obj):
445 def doc(self, obj):
445 return self._doc
446 return self._doc
446
447
447 def attrtype(self, obj):
448 def attrtype(self, obj):
448 return "iter"
449 return "iter"
449
450
450 def valuetype(self, obj):
451 def valuetype(self, obj):
451 return noitem
452 return noitem
452
453
453 def value(self, obj):
454 def value(self, obj):
454 return noitem
455 return noitem
455
456
456 def iter(self, obj):
457 def iter(self, obj):
457 return xiter(getattr(obj, self._name))
458 return xiter(getattr(obj, self._name))
458
459
459 def __repr__(self):
460 def __repr__(self):
460 if self._doc is None:
461 if self._doc is None:
461 return "IterAttribute(%r)" % self._name
462 return "IterAttribute(%r)" % self._name
462 else:
463 else:
463 return "IterAttribute(%r, %r)" % (self._name, self._doc)
464 return "IterAttribute(%r, %r)" % (self._name, self._doc)
464
465
465
466
466 class IterMethodDescriptor(Descriptor):
467 class IterMethodDescriptor(Descriptor):
467 """
468 """
468 An ``IterMethodDescriptor`` works like an ``MethodDescriptor`` but doesn't
469 An ``IterMethodDescriptor`` works like an ``MethodDescriptor`` but doesn't
469 return an attribute values (because this value might be e.g. a large list).
470 return an attribute values (because this value might be e.g. a large list).
470 """
471 """
471 __slots__ = ("_name", "_doc")
472 __slots__ = ("_name", "_doc")
472
473
473 def __init__(self, name, doc=None):
474 def __init__(self, name, doc=None):
474 self._name = name
475 self._name = name
475 self._doc = doc
476 self._doc = doc
476
477
477 def key(self):
478 def key(self):
478 return self._name
479 return self._name
479
480
480 def doc(self, obj):
481 def doc(self, obj):
481 if self._doc is None:
482 if self._doc is None:
482 return getattr(obj, self._name).__doc__
483 return getattr(obj, self._name).__doc__
483 return self._doc
484 return self._doc
484
485
485 def attrtype(self, obj):
486 def attrtype(self, obj):
486 return "itermethod"
487 return "itermethod"
487
488
488 def valuetype(self, obj):
489 def valuetype(self, obj):
489 return noitem
490 return noitem
490
491
491 def value(self, obj):
492 def value(self, obj):
492 return noitem
493 return noitem
493
494
494 def iter(self, obj):
495 def iter(self, obj):
495 return xiter(getattr(obj, self._name)())
496 return xiter(getattr(obj, self._name)())
496
497
497 def __repr__(self):
498 def __repr__(self):
498 if self._doc is None:
499 if self._doc is None:
499 return "IterMethod(%r)" % self._name
500 return "IterMethod(%r)" % self._name
500 else:
501 else:
501 return "IterMethod(%r, %r)" % (self._name, self._doc)
502 return "IterMethod(%r, %r)" % (self._name, self._doc)
502
503
503
504
504 class FunctionDescriptor(Descriptor):
505 class FunctionDescriptor(Descriptor):
505 """
506 """
506 A ``FunctionDescriptor`` turns a function into a descriptor. The function
507 A ``FunctionDescriptor`` turns a function into a descriptor. The function
507 will be called with the object to get the type and value of the attribute.
508 will be called with the object to get the type and value of the attribute.
508 """
509 """
509 __slots__ = ("_function", "_name", "_doc")
510 __slots__ = ("_function", "_name", "_doc")
510
511
511 def __init__(self, function, name=None, doc=None):
512 def __init__(self, function, name=None, doc=None):
512 self._function = function
513 self._function = function
513 self._name = name
514 self._name = name
514 self._doc = doc
515 self._doc = doc
515
516
516 def key(self):
517 def key(self):
517 return self._function
518 return self._function
518
519
519 def name(self):
520 def name(self):
520 if self._name is not None:
521 if self._name is not None:
521 return self._name
522 return self._name
522 return getattr(self._function, "__xname__", self._function.__name__)
523 return getattr(self._function, "__xname__", self._function.__name__)
523
524
524 def doc(self, obj):
525 def doc(self, obj):
525 if self._doc is None:
526 if self._doc is None:
526 return self._function.__doc__
527 return self._function.__doc__
527 return self._doc
528 return self._doc
528
529
529 def attrtype(self, obj):
530 def attrtype(self, obj):
530 return "function"
531 return "function"
531
532
532 def valuetype(self, obj):
533 def valuetype(self, obj):
533 return type(self._function(obj))
534 return type(self._function(obj))
534
535
535 def value(self, obj):
536 def value(self, obj):
536 return self._function(obj)
537 return self._function(obj)
537
538
538 def __repr__(self):
539 def __repr__(self):
539 if self._doc is None:
540 if self._doc is None:
540 return "Function(%r)" % self._name
541 return "Function(%r)" % self._name
541 else:
542 else:
542 return "Function(%r, %r)" % (self._name, self._doc)
543 return "Function(%r, %r)" % (self._name, self._doc)
543
544
544
545
545 class Table(object):
546 class Table(object):
546 """
547 """
547 A ``Table`` is an object that produces items (just like a normal Python
548 A ``Table`` is an object that produces items (just like a normal Python
548 iterator/generator does) and can be used as the first object in a pipeline
549 iterator/generator does) and can be used as the first object in a pipeline
549 expression. The displayhook will open the default browser for such an object
550 expression. The displayhook will open the default browser for such an object
550 (instead of simply printing the ``repr()`` result).
551 (instead of simply printing the ``repr()`` result).
551 """
552 """
552
553
553 # We want to support ``foo`` and ``foo()`` in pipeline expression:
554 # We want to support ``foo`` and ``foo()`` in pipeline expression:
554 # So we implement the required operators (``|`` and ``+``) in the metaclass,
555 # So we implement the required operators (``|`` and ``+``) in the metaclass,
555 # instantiate the class and forward the operator to the instance
556 # instantiate the class and forward the operator to the instance
556 class __metaclass__(type):
557 class __metaclass__(type):
557 def __iter__(self):
558 def __iter__(self):
558 return iter(self())
559 return iter(self())
559
560
560 def __or__(self, other):
561 def __or__(self, other):
561 return self() | other
562 return self() | other
562
563
563 def __add__(self, other):
564 def __add__(self, other):
564 return self() + other
565 return self() + other
565
566
566 def __radd__(self, other):
567 def __radd__(self, other):
567 return other + self()
568 return other + self()
568
569
569 def __getitem__(self, index):
570 def __getitem__(self, index):
570 return self()[index]
571 return self()[index]
571
572
572 def __getitem__(self, index):
573 def __getitem__(self, index):
573 return item(self, index)
574 return item(self, index)
574
575
575 def __contains__(self, item):
576 def __contains__(self, item):
576 for haveitem in self:
577 for haveitem in self:
577 if item == haveitem:
578 if item == haveitem:
578 return True
579 return True
579 return False
580 return False
580
581
581 def __or__(self, other):
582 def __or__(self, other):
582 # autoinstantiate right hand side
583 # autoinstantiate right hand side
583 if isinstance(other, type) and issubclass(other, (Table, Display)):
584 if isinstance(other, type) and issubclass(other, (Table, Display)):
584 other = other()
585 other = other()
585 # treat simple strings and functions as ``ieval`` instances
586 # treat simple strings and functions as ``ieval`` instances
586 elif not isinstance(other, Display) and not isinstance(other, Table):
587 elif not isinstance(other, Display) and not isinstance(other, Table):
587 other = ieval(other)
588 other = ieval(other)
588 # forward operations to the right hand side
589 # forward operations to the right hand side
589 return other.__ror__(self)
590 return other.__ror__(self)
590
591
591 def __add__(self, other):
592 def __add__(self, other):
592 # autoinstantiate right hand side
593 # autoinstantiate right hand side
593 if isinstance(other, type) and issubclass(other, Table):
594 if isinstance(other, type) and issubclass(other, Table):
594 other = other()
595 other = other()
595 return ichain(self, other)
596 return ichain(self, other)
596
597
597 def __radd__(self, other):
598 def __radd__(self, other):
598 # autoinstantiate left hand side
599 # autoinstantiate left hand side
599 if isinstance(other, type) and issubclass(other, Table):
600 if isinstance(other, type) and issubclass(other, Table):
600 other = other()
601 other = other()
601 return ichain(other, self)
602 return ichain(other, self)
602
603
603
604
604 class Pipe(Table):
605 class Pipe(Table):
605 """
606 """
606 A ``Pipe`` is an object that can be used in a pipeline expression. It
607 A ``Pipe`` is an object that can be used in a pipeline expression. It
607 processes the objects it gets from its input ``Table``/``Pipe``. Note that
608 processes the objects it gets from its input ``Table``/``Pipe``. Note that
608 a ``Pipe`` object can't be used as the first object in a pipeline
609 a ``Pipe`` object can't be used as the first object in a pipeline
609 expression, as it doesn't produces items itself.
610 expression, as it doesn't produces items itself.
610 """
611 """
611 class __metaclass__(Table.__metaclass__):
612 class __metaclass__(Table.__metaclass__):
612 def __ror__(self, input):
613 def __ror__(self, input):
613 return input | self()
614 return input | self()
614
615
615 def __ror__(self, input):
616 def __ror__(self, input):
616 # autoinstantiate left hand side
617 # autoinstantiate left hand side
617 if isinstance(input, type) and issubclass(input, Table):
618 if isinstance(input, type) and issubclass(input, Table):
618 input = input()
619 input = input()
619 self.input = input
620 self.input = input
620 return self
621 return self
621
622
622
623
623 def xrepr(item, mode="default"):
624 def xrepr(item, mode="default"):
624 """
625 """
625 Generic function that adds color output and different display modes to ``repr``.
626 Generic function that adds color output and different display modes to ``repr``.
626
627
627 The result of an ``xrepr`` call is iterable and consists of ``(style, string)``
628 The result of an ``xrepr`` call is iterable and consists of ``(style, string)``
628 tuples. The ``style`` in this tuple must be a ``Style`` object from the
629 tuples. The ``style`` in this tuple must be a ``Style`` object from the
629 ``astring`` module. To reconfigure the output the first yielded tuple can be
630 ``astring`` module. To reconfigure the output the first yielded tuple can be
630 a ``(aligment, full)`` tuple instead of a ``(style, string)`` tuple.
631 a ``(aligment, full)`` tuple instead of a ``(style, string)`` tuple.
631 ``alignment`` can be -1 for left aligned, 0 for centered and 1 for right
632 ``alignment`` can be -1 for left aligned, 0 for centered and 1 for right
632 aligned (the default is left alignment). ``full`` is a boolean that specifies
633 aligned (the default is left alignment). ``full`` is a boolean that specifies
633 whether the complete output must be displayed or the ``Display`` object is
634 whether the complete output must be displayed or the ``Display`` object is
634 allowed to stop output after enough text has been produced (e.g. a syntax
635 allowed to stop output after enough text has been produced (e.g. a syntax
635 highlighted text line would use ``True``, but for a large data structure
636 highlighted text line would use ``True``, but for a large data structure
636 (i.e. a nested list, tuple or dictionary) ``False`` would be used).
637 (i.e. a nested list, tuple or dictionary) ``False`` would be used).
637 The default is full output.
638 The default is full output.
638
639
639 There are four different possible values for ``mode`` depending on where
640 There are four different possible values for ``mode`` depending on where
640 the ``Display`` object will display ``item``:
641 the ``Display`` object will display ``item``:
641
642
642 * ``"header"``: ``item`` will be displayed in a header line (this is used by
643 ``"header"``
643 ``ibrowse``).
644 ``item`` will be displayed in a header line (this is used by ``ibrowse``).
644 * ``"footer"``: ``item`` will be displayed in a footer line (this is used by
645
645 ``ibrowse``).
646 ``"footer"``
646 * ``"cell"``: ``item`` will be displayed in a table cell/list.
647 ``item`` will be displayed in a footer line (this is used by ``ibrowse``).
647 * ``"default"``: default mode. If an ``xrepr`` implementation recursively
648
648 outputs objects, ``"default"`` must be passed in the recursive calls to
649 ``"cell"``
649 ``xrepr``.
650 ``item`` will be displayed in a table cell/list.
651
652 ``"default"``
653 default mode. If an ``xrepr`` implementation recursively outputs objects,
654 ``"default"`` must be passed in the recursive calls to ``xrepr``.
650
655
651 If no implementation is registered for ``item``, ``xrepr`` will try the
656 If no implementation is registered for ``item``, ``xrepr`` will try the
652 ``__xrepr__`` method on ``item``. If ``item`` doesn't have an ``__xrepr__``
657 ``__xrepr__`` method on ``item``. If ``item`` doesn't have an ``__xrepr__``
653 method it falls back to ``repr``/``__repr__`` for all modes.
658 method it falls back to ``repr``/``__repr__`` for all modes.
654 """
659 """
655 try:
660 try:
656 func = item.__xrepr__
661 func = item.__xrepr__
657 except AttributeError:
662 except AttributeError:
658 yield (astyle.style_default, repr(item))
663 yield (astyle.style_default, repr(item))
659 else:
664 else:
660 try:
665 try:
661 for x in func(mode):
666 for x in func(mode):
662 yield x
667 yield x
663 except (KeyboardInterrupt, SystemExit):
668 except (KeyboardInterrupt, SystemExit):
664 raise
669 raise
665 except Exception:
670 except Exception:
666 yield (astyle.style_default, repr(item))
671 yield (astyle.style_default, repr(item))
667 xrepr = simplegeneric.generic(xrepr)
672 xrepr = simplegeneric.generic(xrepr)
668
673
669
674
670 def xrepr_none(self, mode="default"):
675 def xrepr_none(self, mode="default"):
671 yield (astyle.style_type_none, repr(self))
676 yield (astyle.style_type_none, repr(self))
672 xrepr.when_object(None)(xrepr_none)
677 xrepr.when_object(None)(xrepr_none)
673
678
674
679
675 def xrepr_noitem(self, mode="default"):
680 def xrepr_noitem(self, mode="default"):
676 yield (2, True)
681 yield (2, True)
677 yield (astyle.style_nodata, "<?>")
682 yield (astyle.style_nodata, "<?>")
678 xrepr.when_object(noitem)(xrepr_noitem)
683 xrepr.when_object(noitem)(xrepr_noitem)
679
684
680
685
681 def xrepr_bool(self, mode="default"):
686 def xrepr_bool(self, mode="default"):
682 yield (astyle.style_type_bool, repr(self))
687 yield (astyle.style_type_bool, repr(self))
683 xrepr.when_type(bool)(xrepr_bool)
688 xrepr.when_type(bool)(xrepr_bool)
684
689
685
690
686 def xrepr_str(self, mode="default"):
691 def xrepr_str(self, mode="default"):
687 if mode == "cell":
692 if mode == "cell":
688 yield (astyle.style_default, repr(self.expandtabs(tab))[1:-1])
693 yield (astyle.style_default, repr(self.expandtabs(tab))[1:-1])
689 else:
694 else:
690 yield (astyle.style_default, repr(self))
695 yield (astyle.style_default, repr(self))
691 xrepr.when_type(str)(xrepr_str)
696 xrepr.when_type(str)(xrepr_str)
692
697
693
698
694 def xrepr_unicode(self, mode="default"):
699 def xrepr_unicode(self, mode="default"):
695 if mode == "cell":
700 if mode == "cell":
696 yield (astyle.style_default, repr(self.expandtabs(tab))[2:-1])
701 yield (astyle.style_default, repr(self.expandtabs(tab))[2:-1])
697 else:
702 else:
698 yield (astyle.style_default, repr(self))
703 yield (astyle.style_default, repr(self))
699 xrepr.when_type(unicode)(xrepr_unicode)
704 xrepr.when_type(unicode)(xrepr_unicode)
700
705
701
706
702 def xrepr_number(self, mode="default"):
707 def xrepr_number(self, mode="default"):
703 yield (1, True)
708 yield (1, True)
704 yield (astyle.style_type_number, repr(self))
709 yield (astyle.style_type_number, repr(self))
705 xrepr.when_type(int)(xrepr_number)
710 xrepr.when_type(int)(xrepr_number)
706 xrepr.when_type(long)(xrepr_number)
711 xrepr.when_type(long)(xrepr_number)
707 xrepr.when_type(float)(xrepr_number)
712 xrepr.when_type(float)(xrepr_number)
708
713
709
714
710 def xrepr_complex(self, mode="default"):
715 def xrepr_complex(self, mode="default"):
711 yield (astyle.style_type_number, repr(self))
716 yield (astyle.style_type_number, repr(self))
712 xrepr.when_type(complex)(xrepr_number)
717 xrepr.when_type(complex)(xrepr_number)
713
718
714
719
715 def xrepr_datetime(self, mode="default"):
720 def xrepr_datetime(self, mode="default"):
716 if mode == "cell":
721 if mode == "cell":
717 # Don't use strftime() here, as this requires year >= 1900
722 # Don't use strftime() here, as this requires year >= 1900
718 yield (astyle.style_type_datetime,
723 yield (astyle.style_type_datetime,
719 "%04d-%02d-%02d %02d:%02d:%02d.%06d" % \
724 "%04d-%02d-%02d %02d:%02d:%02d.%06d" % \
720 (self.year, self.month, self.day,
725 (self.year, self.month, self.day,
721 self.hour, self.minute, self.second,
726 self.hour, self.minute, self.second,
722 self.microsecond),
727 self.microsecond),
723 )
728 )
724 else:
729 else:
725 yield (astyle.style_type_datetime, repr(self))
730 yield (astyle.style_type_datetime, repr(self))
726 xrepr.when_type(datetime.datetime)(xrepr_datetime)
731 xrepr.when_type(datetime.datetime)(xrepr_datetime)
727
732
728
733
729 def xrepr_date(self, mode="default"):
734 def xrepr_date(self, mode="default"):
730 if mode == "cell":
735 if mode == "cell":
731 yield (astyle.style_type_datetime,
736 yield (astyle.style_type_datetime,
732 "%04d-%02d-%02d" % (self.year, self.month, self.day))
737 "%04d-%02d-%02d" % (self.year, self.month, self.day))
733 else:
738 else:
734 yield (astyle.style_type_datetime, repr(self))
739 yield (astyle.style_type_datetime, repr(self))
735 xrepr.when_type(datetime.date)(xrepr_date)
740 xrepr.when_type(datetime.date)(xrepr_date)
736
741
737
742
738 def xrepr_time(self, mode="default"):
743 def xrepr_time(self, mode="default"):
739 if mode == "cell":
744 if mode == "cell":
740 yield (astyle.style_type_datetime,
745 yield (astyle.style_type_datetime,
741 "%02d:%02d:%02d.%06d" % \
746 "%02d:%02d:%02d.%06d" % \
742 (self.hour, self.minute, self.second, self.microsecond))
747 (self.hour, self.minute, self.second, self.microsecond))
743 else:
748 else:
744 yield (astyle.style_type_datetime, repr(self))
749 yield (astyle.style_type_datetime, repr(self))
745 xrepr.when_type(datetime.time)(xrepr_time)
750 xrepr.when_type(datetime.time)(xrepr_time)
746
751
747
752
748 def xrepr_timedelta(self, mode="default"):
753 def xrepr_timedelta(self, mode="default"):
749 yield (astyle.style_type_datetime, repr(self))
754 yield (astyle.style_type_datetime, repr(self))
750 xrepr.when_type(datetime.timedelta)(xrepr_timedelta)
755 xrepr.when_type(datetime.timedelta)(xrepr_timedelta)
751
756
752
757
753 def xrepr_type(self, mode="default"):
758 def xrepr_type(self, mode="default"):
754 if self.__module__ == "__builtin__":
759 if self.__module__ == "__builtin__":
755 yield (astyle.style_type_type, self.__name__)
760 yield (astyle.style_type_type, self.__name__)
756 else:
761 else:
757 yield (astyle.style_type_type, "%s.%s" % (self.__module__, self.__name__))
762 yield (astyle.style_type_type, "%s.%s" % (self.__module__, self.__name__))
758 xrepr.when_type(type)(xrepr_type)
763 xrepr.when_type(type)(xrepr_type)
759
764
760
765
761 def xrepr_exception(self, mode="default"):
766 def xrepr_exception(self, mode="default"):
762 if self.__class__.__module__ == "exceptions":
767 if self.__class__.__module__ == "exceptions":
763 classname = self.__class__.__name__
768 classname = self.__class__.__name__
764 else:
769 else:
765 classname = "%s.%s" % \
770 classname = "%s.%s" % \
766 (self.__class__.__module__, self.__class__.__name__)
771 (self.__class__.__module__, self.__class__.__name__)
767 if mode == "header" or mode == "footer":
772 if mode == "header" or mode == "footer":
768 yield (astyle.style_error, "%s: %s" % (classname, self))
773 yield (astyle.style_error, "%s: %s" % (classname, self))
769 else:
774 else:
770 yield (astyle.style_error, classname)
775 yield (astyle.style_error, classname)
771 xrepr.when_type(Exception)(xrepr_exception)
776 xrepr.when_type(Exception)(xrepr_exception)
772
777
773
778
774 def xrepr_listtuple(self, mode="default"):
779 def xrepr_listtuple(self, mode="default"):
775 if mode == "header" or mode == "footer":
780 if mode == "header" or mode == "footer":
776 if self.__class__.__module__ == "__builtin__":
781 if self.__class__.__module__ == "__builtin__":
777 classname = self.__class__.__name__
782 classname = self.__class__.__name__
778 else:
783 else:
779 classname = "%s.%s" % \
784 classname = "%s.%s" % \
780 (self.__class__.__module__,self.__class__.__name__)
785 (self.__class__.__module__,self.__class__.__name__)
781 yield (astyle.style_default,
786 yield (astyle.style_default,
782 "<%s object with %d items at 0x%x>" % \
787 "<%s object with %d items at 0x%x>" % \
783 (classname, len(self), id(self)))
788 (classname, len(self), id(self)))
784 else:
789 else:
785 yield (-1, False)
790 yield (-1, False)
786 if isinstance(self, list):
791 if isinstance(self, list):
787 yield (astyle.style_default, "[")
792 yield (astyle.style_default, "[")
788 end = "]"
793 end = "]"
789 else:
794 else:
790 yield (astyle.style_default, "(")
795 yield (astyle.style_default, "(")
791 end = ")"
796 end = ")"
792 for (i, subself) in enumerate(self):
797 for (i, subself) in enumerate(self):
793 if i:
798 if i:
794 yield (astyle.style_default, ", ")
799 yield (astyle.style_default, ", ")
795 for part in xrepr(subself, "default"):
800 for part in xrepr(subself, "default"):
796 yield part
801 yield part
797 yield (astyle.style_default, end)
802 yield (astyle.style_default, end)
798 xrepr.when_type(list)(xrepr_listtuple)
803 xrepr.when_type(list)(xrepr_listtuple)
799 xrepr.when_type(tuple)(xrepr_listtuple)
804 xrepr.when_type(tuple)(xrepr_listtuple)
800
805
801
806
802 def xrepr_dict(self, mode="default"):
807 def xrepr_dict(self, mode="default"):
803 if mode == "header" or mode == "footer":
808 if mode == "header" or mode == "footer":
804 if self.__class__.__module__ == "__builtin__":
809 if self.__class__.__module__ == "__builtin__":
805 classname = self.__class__.__name__
810 classname = self.__class__.__name__
806 else:
811 else:
807 classname = "%s.%s" % \
812 classname = "%s.%s" % \
808 (self.__class__.__module__,self.__class__.__name__)
813 (self.__class__.__module__,self.__class__.__name__)
809 yield (astyle.style_default,
814 yield (astyle.style_default,
810 "<%s object with %d items at 0x%x>" % \
815 "<%s object with %d items at 0x%x>" % \
811 (classname, len(self), id(self)))
816 (classname, len(self), id(self)))
812 else:
817 else:
813 yield (-1, False)
818 yield (-1, False)
814 if isinstance(self, dict):
819 if isinstance(self, dict):
815 yield (astyle.style_default, "{")
820 yield (astyle.style_default, "{")
816 end = "}"
821 end = "}"
817 else:
822 else:
818 yield (astyle.style_default, "dictproxy((")
823 yield (astyle.style_default, "dictproxy((")
819 end = "})"
824 end = "})"
820 for (i, (key, value)) in enumerate(self.iteritems()):
825 for (i, (key, value)) in enumerate(self.iteritems()):
821 if i:
826 if i:
822 yield (astyle.style_default, ", ")
827 yield (astyle.style_default, ", ")
823 for part in xrepr(key, "default"):
828 for part in xrepr(key, "default"):
824 yield part
829 yield part
825 yield (astyle.style_default, ": ")
830 yield (astyle.style_default, ": ")
826 for part in xrepr(value, "default"):
831 for part in xrepr(value, "default"):
827 yield part
832 yield part
828 yield (astyle.style_default, end)
833 yield (astyle.style_default, end)
829 xrepr.when_type(dict)(xrepr_dict)
834 xrepr.when_type(dict)(xrepr_dict)
830 xrepr.when_type(types.DictProxyType)(xrepr_dict)
835 xrepr.when_type(types.DictProxyType)(xrepr_dict)
831
836
832
837
833 def upgradexattr(attr):
838 def upgradexattr(attr):
834 """
839 """
835 Convert an attribute descriptor string to a real descriptor object.
840 Convert an attribute descriptor string to a real descriptor object.
836
841
837 If attr already is a descriptor object return if unmodified. A
842 If attr already is a descriptor object return if unmodified. A
838 ``SelfDescriptor`` will be returned if ``attr`` is ``None``. ``"foo"``
843 ``SelfDescriptor`` will be returned if ``attr`` is ``None``. ``"foo"``
839 returns an ``AttributeDescriptor`` for the attribute named ``"foo"``.
844 returns an ``AttributeDescriptor`` for the attribute named ``"foo"``.
840 ``"foo()"`` returns a ``MethodDescriptor`` for the method named ``"foo"``.
845 ``"foo()"`` returns a ``MethodDescriptor`` for the method named ``"foo"``.
841 ``"-foo"`` will return an ``IterAttributeDescriptor`` for the attribute
846 ``"-foo"`` will return an ``IterAttributeDescriptor`` for the attribute
842 named ``"foo"`` and ``"-foo()"`` will return an ``IterMethodDescriptor``
847 named ``"foo"`` and ``"-foo()"`` will return an ``IterMethodDescriptor``
843 for the method named ``"foo"``. Furthermore integer will return the appropriate
848 for the method named ``"foo"``. Furthermore integer will return the appropriate
844 ``IndexDescriptor`` and callables will return a ``FunctionDescriptor``.
849 ``IndexDescriptor`` and callables will return a ``FunctionDescriptor``.
845 """
850 """
846 if attr is None:
851 if attr is None:
847 return selfdescriptor
852 return selfdescriptor
848 elif isinstance(attr, Descriptor):
853 elif isinstance(attr, Descriptor):
849 return attr
854 return attr
850 elif isinstance(attr, str):
855 elif isinstance(attr, str):
851 if attr.endswith("()"):
856 if attr.endswith("()"):
852 if attr.startswith("-"):
857 if attr.startswith("-"):
853 return IterMethodDescriptor(attr[1:-2])
858 return IterMethodDescriptor(attr[1:-2])
854 else:
859 else:
855 return MethodDescriptor(attr[:-2])
860 return MethodDescriptor(attr[:-2])
856 else:
861 else:
857 if attr.startswith("-"):
862 if attr.startswith("-"):
858 return IterAttributeDescriptor(attr[1:])
863 return IterAttributeDescriptor(attr[1:])
859 else:
864 else:
860 return AttributeDescriptor(attr)
865 return AttributeDescriptor(attr)
861 elif isinstance(attr, (int, long)):
866 elif isinstance(attr, (int, long)):
862 return IndexDescriptor(attr)
867 return IndexDescriptor(attr)
863 elif callable(attr):
868 elif callable(attr):
864 return FunctionDescriptor(attr)
869 return FunctionDescriptor(attr)
865 else:
870 else:
866 raise TypeError("can't handle descriptor %r" % attr)
871 raise TypeError("can't handle descriptor %r" % attr)
867
872
868
873
869 def xattrs(item, mode="default"):
874 def xattrs(item, mode="default"):
870 """
875 """
871 Generic function that returns an iterable of attribute descriptors
876 Generic function that returns an iterable of attribute descriptors
872 to be used for displaying the attributes ob the object ``item`` in display
877 to be used for displaying the attributes ob the object ``item`` in display
873 mode ``mode``.
878 mode ``mode``.
874
879
875 There are two possible modes:
880 There are two possible modes:
876
881
877 * ``"detail"``: The ``Display`` object wants to display a detailed list
882 ``"detail"``
878 of the object attributes.
883 The ``Display`` object wants to display a detailed list of the object
879 * ``"default"``: The ``Display`` object wants to display the object in a
884 attributes.
880 list view.
885
886 ``"default"``
887 The ``Display`` object wants to display the object in a list view.
881
888
882 If no implementation is registered for the object ``item`` ``xattrs`` falls
889 If no implementation is registered for the object ``item`` ``xattrs`` falls
883 back to trying the ``__xattrs__`` method of the object. If this doesn't
890 back to trying the ``__xattrs__`` method of the object. If this doesn't
884 exist either, ``dir(item)`` is used for ``"detail"`` mode and ``(None,)``
891 exist either, ``dir(item)`` is used for ``"detail"`` mode and ``(None,)``
885 for ``"default"`` mode.
892 for ``"default"`` mode.
886
893
887 The implementation must yield attribute descriptors (see the class
894 The implementation must yield attribute descriptors (see the class
888 ``Descriptor`` for more info). The ``__xattrs__`` method may also return
895 ``Descriptor`` for more info). The ``__xattrs__`` method may also return
889 attribute descriptor strings (and ``None``) which will be converted to real
896 attribute descriptor strings (and ``None``) which will be converted to real
890 descriptors by ``upgradexattr()``.
897 descriptors by ``upgradexattr()``.
891 """
898 """
892 try:
899 try:
893 func = item.__xattrs__
900 func = item.__xattrs__
894 except AttributeError:
901 except AttributeError:
895 if mode == "detail":
902 if mode == "detail":
896 for attrname in dir(item):
903 for attrname in dir(item):
897 yield AttributeDescriptor(attrname)
904 yield AttributeDescriptor(attrname)
898 else:
905 else:
899 yield selfdescriptor
906 yield selfdescriptor
900 else:
907 else:
901 for attr in func(mode):
908 for attr in func(mode):
902 yield upgradexattr(attr)
909 yield upgradexattr(attr)
903 xattrs = simplegeneric.generic(xattrs)
910 xattrs = simplegeneric.generic(xattrs)
904
911
905
912
906 def xattrs_complex(self, mode="default"):
913 def xattrs_complex(self, mode="default"):
907 if mode == "detail":
914 if mode == "detail":
908 return (AttributeDescriptor("real"), AttributeDescriptor("imag"))
915 return (AttributeDescriptor("real"), AttributeDescriptor("imag"))
909 return (selfdescriptor,)
916 return (selfdescriptor,)
910 xattrs.when_type(complex)(xattrs_complex)
917 xattrs.when_type(complex)(xattrs_complex)
911
918
912
919
913 def _isdict(item):
920 def _isdict(item):
914 try:
921 try:
915 itermeth = item.__class__.__iter__
922 itermeth = item.__class__.__iter__
916 except (AttributeError, TypeError):
923 except (AttributeError, TypeError):
917 return False
924 return False
918 return itermeth is dict.__iter__ or itermeth is types.DictProxyType.__iter__
925 return itermeth is dict.__iter__ or itermeth is types.DictProxyType.__iter__
919
926
920
927
921 def _isstr(item):
928 def _isstr(item):
922 if not isinstance(item, basestring):
929 if not isinstance(item, basestring):
923 return False
930 return False
924 try:
931 try:
925 itermeth = item.__class__.__iter__
932 itermeth = item.__class__.__iter__
926 except AttributeError:
933 except AttributeError:
927 return True
934 return True
928 return False # ``__iter__`` has been redefined
935 return False # ``__iter__`` has been redefined
929
936
930
937
931 def xiter(item):
938 def xiter(item):
932 """
939 """
933 Generic function that implements iteration for pipeline expression. If no
940 Generic function that implements iteration for pipeline expression. If no
934 implementation is registered for ``item`` ``xiter`` falls back to ``iter``.
941 implementation is registered for ``item`` ``xiter`` falls back to ``iter``.
935 """
942 """
936 try:
943 try:
937 func = item.__xiter__
944 func = item.__xiter__
938 except AttributeError:
945 except AttributeError:
939 if _isdict(item):
946 if _isdict(item):
940 def items(item):
947 def items(item):
941 fields = ("key", "value")
948 fields = ("key", "value")
942 for (key, value) in item.iteritems():
949 for (key, value) in item.iteritems():
943 yield Fields(fields, key=key, value=value)
950 yield Fields(fields, key=key, value=value)
944 return items(item)
951 return items(item)
945 elif isinstance(item, new.module):
952 elif isinstance(item, new.module):
946 def items(item):
953 def items(item):
947 fields = ("key", "value")
954 fields = ("key", "value")
948 for key in sorted(item.__dict__):
955 for key in sorted(item.__dict__):
949 yield Fields(fields, key=key, value=getattr(item, key))
956 yield Fields(fields, key=key, value=getattr(item, key))
950 return items(item)
957 return items(item)
951 elif _isstr(item):
958 elif _isstr(item):
952 if not item:
959 if not item:
953 raise ValueError("can't enter empty string")
960 raise ValueError("can't enter empty string")
954 lines = item.splitlines()
961 lines = item.splitlines()
955 if len(lines) == 1:
962 if len(lines) == 1:
956 def iterone(item):
963 def iterone(item):
957 yield item
964 yield item
958 return iterone(item)
965 return iterone(item)
959 else:
966 else:
960 return iter(lines)
967 return iter(lines)
961 return iter(item)
968 return iter(item)
962 else:
969 else:
963 return iter(func()) # iter() just to be safe
970 return iter(func()) # iter() just to be safe
964 xiter = simplegeneric.generic(xiter)
971 xiter = simplegeneric.generic(xiter)
965
972
966
973
967 class ichain(Pipe):
974 class ichain(Pipe):
968 """
975 """
969 Chains multiple ``Table``s into one.
976 Chains multiple ``Table``s into one.
970 """
977 """
971
978
972 def __init__(self, *iters):
979 def __init__(self, *iters):
973 self.iters = iters
980 self.iters = iters
974
981
975 def __iter__(self):
982 def __iter__(self):
976 return itertools.chain(*self.iters)
983 return itertools.chain(*self.iters)
977
984
978 def __xrepr__(self, mode="default"):
985 def __xrepr__(self, mode="default"):
979 if mode == "header" or mode == "footer":
986 if mode == "header" or mode == "footer":
980 for (i, item) in enumerate(self.iters):
987 for (i, item) in enumerate(self.iters):
981 if i:
988 if i:
982 yield (astyle.style_default, "+")
989 yield (astyle.style_default, "+")
983 if isinstance(item, Pipe):
990 if isinstance(item, Pipe):
984 yield (astyle.style_default, "(")
991 yield (astyle.style_default, "(")
985 for part in xrepr(item, mode):
992 for part in xrepr(item, mode):
986 yield part
993 yield part
987 if isinstance(item, Pipe):
994 if isinstance(item, Pipe):
988 yield (astyle.style_default, ")")
995 yield (astyle.style_default, ")")
989 else:
996 else:
990 yield (astyle.style_default, repr(self))
997 yield (astyle.style_default, repr(self))
991
998
992 def __repr__(self):
999 def __repr__(self):
993 args = ", ".join([repr(it) for it in self.iters])
1000 args = ", ".join([repr(it) for it in self.iters])
994 return "%s.%s(%s)" % \
1001 return "%s.%s(%s)" % \
995 (self.__class__.__module__, self.__class__.__name__, args)
1002 (self.__class__.__module__, self.__class__.__name__, args)
996
1003
997
1004
998 class ifile(path.path):
1005 class ifile(path.path):
999 """
1006 """
1000 file (or directory) object.
1007 file (or directory) object.
1001 """
1008 """
1002
1009
1003 def getmode(self):
1010 def getmode(self):
1004 return self.stat().st_mode
1011 return self.stat().st_mode
1005 mode = property(getmode, None, None, "Access mode")
1012 mode = property(getmode, None, None, "Access mode")
1006
1013
1007 def gettype(self):
1014 def gettype(self):
1008 data = [
1015 data = [
1009 (stat.S_ISREG, "file"),
1016 (stat.S_ISREG, "file"),
1010 (stat.S_ISDIR, "dir"),
1017 (stat.S_ISDIR, "dir"),
1011 (stat.S_ISCHR, "chardev"),
1018 (stat.S_ISCHR, "chardev"),
1012 (stat.S_ISBLK, "blockdev"),
1019 (stat.S_ISBLK, "blockdev"),
1013 (stat.S_ISFIFO, "fifo"),
1020 (stat.S_ISFIFO, "fifo"),
1014 (stat.S_ISLNK, "symlink"),
1021 (stat.S_ISLNK, "symlink"),
1015 (stat.S_ISSOCK,"socket"),
1022 (stat.S_ISSOCK,"socket"),
1016 ]
1023 ]
1017 lstat = self.lstat()
1024 lstat = self.lstat()
1018 if lstat is not None:
1025 if lstat is not None:
1019 types = set([text for (func, text) in data if func(lstat.st_mode)])
1026 types = set([text for (func, text) in data if func(lstat.st_mode)])
1020 else:
1027 else:
1021 types = set()
1028 types = set()
1022 m = self.mode
1029 m = self.mode
1023 types.update([text for (func, text) in data if func(m)])
1030 types.update([text for (func, text) in data if func(m)])
1024 return ", ".join(types)
1031 return ", ".join(types)
1025 type = property(gettype, None, None, "file type (file, directory, link, etc.)")
1032 type = property(gettype, None, None, "file type (file, directory, link, etc.)")
1026
1033
1027 def getmodestr(self):
1034 def getmodestr(self):
1028 m = self.mode
1035 m = self.mode
1029 data = [
1036 data = [
1030 (stat.S_IRUSR, "-r"),
1037 (stat.S_IRUSR, "-r"),
1031 (stat.S_IWUSR, "-w"),
1038 (stat.S_IWUSR, "-w"),
1032 (stat.S_IXUSR, "-x"),
1039 (stat.S_IXUSR, "-x"),
1033 (stat.S_IRGRP, "-r"),
1040 (stat.S_IRGRP, "-r"),
1034 (stat.S_IWGRP, "-w"),
1041 (stat.S_IWGRP, "-w"),
1035 (stat.S_IXGRP, "-x"),
1042 (stat.S_IXGRP, "-x"),
1036 (stat.S_IROTH, "-r"),
1043 (stat.S_IROTH, "-r"),
1037 (stat.S_IWOTH, "-w"),
1044 (stat.S_IWOTH, "-w"),
1038 (stat.S_IXOTH, "-x"),
1045 (stat.S_IXOTH, "-x"),
1039 ]
1046 ]
1040 return "".join([text[bool(m&bit)] for (bit, text) in data])
1047 return "".join([text[bool(m&bit)] for (bit, text) in data])
1041
1048
1042 modestr = property(getmodestr, None, None, "Access mode as string")
1049 modestr = property(getmodestr, None, None, "Access mode as string")
1043
1050
1044 def getblocks(self):
1051 def getblocks(self):
1045 return self.stat().st_blocks
1052 return self.stat().st_blocks
1046 blocks = property(getblocks, None, None, "File size in blocks")
1053 blocks = property(getblocks, None, None, "File size in blocks")
1047
1054
1048 def getblksize(self):
1055 def getblksize(self):
1049 return self.stat().st_blksize
1056 return self.stat().st_blksize
1050 blksize = property(getblksize, None, None, "Filesystem block size")
1057 blksize = property(getblksize, None, None, "Filesystem block size")
1051
1058
1052 def getdev(self):
1059 def getdev(self):
1053 return self.stat().st_dev
1060 return self.stat().st_dev
1054 dev = property(getdev)
1061 dev = property(getdev)
1055
1062
1056 def getnlink(self):
1063 def getnlink(self):
1057 return self.stat().st_nlink
1064 return self.stat().st_nlink
1058 nlink = property(getnlink, None, None, "Number of links")
1065 nlink = property(getnlink, None, None, "Number of links")
1059
1066
1060 def getuid(self):
1067 def getuid(self):
1061 return self.stat().st_uid
1068 return self.stat().st_uid
1062 uid = property(getuid, None, None, "User id of file owner")
1069 uid = property(getuid, None, None, "User id of file owner")
1063
1070
1064 def getgid(self):
1071 def getgid(self):
1065 return self.stat().st_gid
1072 return self.stat().st_gid
1066 gid = property(getgid, None, None, "Group id of file owner")
1073 gid = property(getgid, None, None, "Group id of file owner")
1067
1074
1068 def getowner(self):
1075 def getowner(self):
1069 stat = self.stat()
1076 stat = self.stat()
1070 try:
1077 try:
1071 return pwd.getpwuid(stat.st_uid).pw_name
1078 return pwd.getpwuid(stat.st_uid).pw_name
1072 except KeyError:
1079 except KeyError:
1073 return stat.st_uid
1080 return stat.st_uid
1074 owner = property(getowner, None, None, "Owner name (or id)")
1081 owner = property(getowner, None, None, "Owner name (or id)")
1075
1082
1076 def getgroup(self):
1083 def getgroup(self):
1077 stat = self.stat()
1084 stat = self.stat()
1078 try:
1085 try:
1079 return grp.getgrgid(stat.st_gid).gr_name
1086 return grp.getgrgid(stat.st_gid).gr_name
1080 except KeyError:
1087 except KeyError:
1081 return stat.st_gid
1088 return stat.st_gid
1082 group = property(getgroup, None, None, "Group name (or id)")
1089 group = property(getgroup, None, None, "Group name (or id)")
1083
1090
1084 def getadate(self):
1091 def getadate(self):
1085 return datetime.datetime.utcfromtimestamp(self.atime)
1092 return datetime.datetime.utcfromtimestamp(self.atime)
1086 adate = property(getadate, None, None, "Access date")
1093 adate = property(getadate, None, None, "Access date")
1087
1094
1088 def getcdate(self):
1095 def getcdate(self):
1089 return datetime.datetime.utcfromtimestamp(self.ctime)
1096 return datetime.datetime.utcfromtimestamp(self.ctime)
1090 cdate = property(getcdate, None, None, "Creation date")
1097 cdate = property(getcdate, None, None, "Creation date")
1091
1098
1092 def getmdate(self):
1099 def getmdate(self):
1093 return datetime.datetime.utcfromtimestamp(self.mtime)
1100 return datetime.datetime.utcfromtimestamp(self.mtime)
1094 mdate = property(getmdate, None, None, "Modification date")
1101 mdate = property(getmdate, None, None, "Modification date")
1095
1102
1096 def mimetype(self):
1103 def mimetype(self):
1097 """
1104 """
1098 Return MIME type guessed from the extension.
1105 Return MIME type guessed from the extension.
1099 """
1106 """
1100 return mimetypes.guess_type(self.basename())[0]
1107 return mimetypes.guess_type(self.basename())[0]
1101
1108
1102 def encoding(self):
1109 def encoding(self):
1103 """
1110 """
1104 Return guessed compression (like "compress" or "gzip").
1111 Return guessed compression (like "compress" or "gzip").
1105 """
1112 """
1106 return mimetypes.guess_type(self.basename())[1]
1113 return mimetypes.guess_type(self.basename())[1]
1107
1114
1108 def __repr__(self):
1115 def __repr__(self):
1109 return "ifile(%s)" % path._base.__repr__(self)
1116 return "ifile(%s)" % path._base.__repr__(self)
1110
1117
1111 if sys.platform == "win32":
1118 if sys.platform == "win32":
1112 defaultattrs = (None, "type", "size", "modestr", "mdate")
1119 defaultattrs = (None, "type", "size", "modestr", "mdate")
1113 else:
1120 else:
1114 defaultattrs = (None, "type", "size", "modestr", "owner", "group", "mdate")
1121 defaultattrs = (None, "type", "size", "modestr", "owner", "group", "mdate")
1115
1122
1116 def __xattrs__(self, mode="default"):
1123 def __xattrs__(self, mode="default"):
1117 if mode == "detail":
1124 if mode == "detail":
1118 return (
1125 return (
1119 "name",
1126 "name",
1120 "basename()",
1127 "basename()",
1121 "abspath()",
1128 "abspath()",
1122 "realpath()",
1129 "realpath()",
1123 "type",
1130 "type",
1124 "mode",
1131 "mode",
1125 "modestr",
1132 "modestr",
1126 "stat()",
1133 "stat()",
1127 "lstat()",
1134 "lstat()",
1128 "uid",
1135 "uid",
1129 "gid",
1136 "gid",
1130 "owner",
1137 "owner",
1131 "group",
1138 "group",
1132 "dev",
1139 "dev",
1133 "nlink",
1140 "nlink",
1134 "ctime",
1141 "ctime",
1135 "mtime",
1142 "mtime",
1136 "atime",
1143 "atime",
1137 "cdate",
1144 "cdate",
1138 "mdate",
1145 "mdate",
1139 "adate",
1146 "adate",
1140 "size",
1147 "size",
1141 "blocks",
1148 "blocks",
1142 "blksize",
1149 "blksize",
1143 "isdir()",
1150 "isdir()",
1144 "islink()",
1151 "islink()",
1145 "mimetype()",
1152 "mimetype()",
1146 "encoding()",
1153 "encoding()",
1147 "-listdir()",
1154 "-listdir()",
1148 "-dirs()",
1155 "-dirs()",
1149 "-files()",
1156 "-files()",
1150 "-walk()",
1157 "-walk()",
1151 "-walkdirs()",
1158 "-walkdirs()",
1152 "-walkfiles()",
1159 "-walkfiles()",
1153 )
1160 )
1154 else:
1161 else:
1155 return self.defaultattrs
1162 return self.defaultattrs
1156
1163
1157
1164
1158 def xiter_ifile(self):
1165 def xiter_ifile(self):
1159 if self.isdir():
1166 if self.isdir():
1160 yield (self / os.pardir).abspath()
1167 yield (self / os.pardir).abspath()
1161 for child in sorted(self.listdir()):
1168 for child in sorted(self.listdir()):
1162 yield child
1169 yield child
1163 else:
1170 else:
1164 f = self.open("rb")
1171 f = self.open("rb")
1165 for line in f:
1172 for line in f:
1166 yield line
1173 yield line
1167 f.close()
1174 f.close()
1168 xiter.when_type(ifile)(xiter_ifile)
1175 xiter.when_type(ifile)(xiter_ifile)
1169
1176
1170
1177
1171 # We need to implement ``xrepr`` for ``ifile`` as a generic function, because
1178 # We need to implement ``xrepr`` for ``ifile`` as a generic function, because
1172 # otherwise ``xrepr_str`` would kick in.
1179 # otherwise ``xrepr_str`` would kick in.
1173 def xrepr_ifile(self, mode="default"):
1180 def xrepr_ifile(self, mode="default"):
1174 try:
1181 try:
1175 if self.isdir():
1182 if self.isdir():
1176 name = "idir"
1183 name = "idir"
1177 style = astyle.style_dir
1184 style = astyle.style_dir
1178 else:
1185 else:
1179 name = "ifile"
1186 name = "ifile"
1180 style = astyle.style_file
1187 style = astyle.style_file
1181 except IOError:
1188 except IOError:
1182 name = "ifile"
1189 name = "ifile"
1183 style = astyle.style_default
1190 style = astyle.style_default
1184 if mode in ("cell", "header", "footer"):
1191 if mode in ("cell", "header", "footer"):
1185 abspath = repr(path._base(self.normpath()))
1192 abspath = repr(path._base(self.normpath()))
1186 if abspath.startswith("u"):
1193 if abspath.startswith("u"):
1187 abspath = abspath[2:-1]
1194 abspath = abspath[2:-1]
1188 else:
1195 else:
1189 abspath = abspath[1:-1]
1196 abspath = abspath[1:-1]
1190 if mode == "cell":
1197 if mode == "cell":
1191 yield (style, abspath)
1198 yield (style, abspath)
1192 else:
1199 else:
1193 yield (style, "%s(%s)" % (name, abspath))
1200 yield (style, "%s(%s)" % (name, abspath))
1194 else:
1201 else:
1195 yield (style, repr(self))
1202 yield (style, repr(self))
1196 xrepr.when_type(ifile)(xrepr_ifile)
1203 xrepr.when_type(ifile)(xrepr_ifile)
1197
1204
1198
1205
1199 class ils(Table):
1206 class ils(Table):
1200 """
1207 """
1201 List the current (or a specified) directory.
1208 List the current (or a specified) directory.
1202
1209
1203 Examples:
1210 Examples::
1204
1211
1205 >>> ils
1212 >>> ils
1206 >>> ils("/usr/local/lib/python2.4")
1213 >>> ils("/usr/local/lib/python2.4")
1207 >>> ils("~")
1214 >>> ils("~")
1208 """
1215 """
1209 def __init__(self, base=os.curdir, dirs=True, files=True):
1216 def __init__(self, base=os.curdir, dirs=True, files=True):
1210 self.base = os.path.expanduser(base)
1217 self.base = os.path.expanduser(base)
1211 self.dirs = dirs
1218 self.dirs = dirs
1212 self.files = files
1219 self.files = files
1213
1220
1214 def __iter__(self):
1221 def __iter__(self):
1215 base = ifile(self.base)
1222 base = ifile(self.base)
1216 yield (base / os.pardir).abspath()
1223 yield (base / os.pardir).abspath()
1217 for child in sorted(base.listdir()):
1224 for child in sorted(base.listdir()):
1218 if self.dirs:
1225 if self.dirs:
1219 if self.files:
1226 if self.files:
1220 yield child
1227 yield child
1221 else:
1228 else:
1222 if child.isdir():
1229 if child.isdir():
1223 yield child
1230 yield child
1224 elif self.files:
1231 elif self.files:
1225 if not child.isdir():
1232 if not child.isdir():
1226 yield child
1233 yield child
1227
1234
1228 def __xrepr__(self, mode="default"):
1235 def __xrepr__(self, mode="default"):
1229 return xrepr(ifile(self.base), mode)
1236 return xrepr(ifile(self.base), mode)
1230
1237
1231 def __repr__(self):
1238 def __repr__(self):
1232 return "%s.%s(%r)" % \
1239 return "%s.%s(%r)" % \
1233 (self.__class__.__module__, self.__class__.__name__, self.base)
1240 (self.__class__.__module__, self.__class__.__name__, self.base)
1234
1241
1235
1242
1236 class iglob(Table):
1243 class iglob(Table):
1237 """
1244 """
1238 List all files and directories matching a specified pattern.
1245 List all files and directories matching a specified pattern.
1239 (See ``glob.glob()`` for more info.).
1246 (See ``glob.glob()`` for more info.).
1240
1247
1241 Examples:
1248 Examples::
1242
1249
1243 >>> iglob("*.py")
1250 >>> iglob("*.py")
1244 """
1251 """
1245 def __init__(self, glob):
1252 def __init__(self, glob):
1246 self.glob = glob
1253 self.glob = glob
1247
1254
1248 def __iter__(self):
1255 def __iter__(self):
1249 for name in glob.glob(self.glob):
1256 for name in glob.glob(self.glob):
1250 yield ifile(name)
1257 yield ifile(name)
1251
1258
1252 def __xrepr__(self, mode="default"):
1259 def __xrepr__(self, mode="default"):
1253 if mode == "header" or mode == "footer" or mode == "cell":
1260 if mode == "header" or mode == "footer" or mode == "cell":
1254 yield (astyle.style_default,
1261 yield (astyle.style_default,
1255 "%s(%r)" % (self.__class__.__name__, self.glob))
1262 "%s(%r)" % (self.__class__.__name__, self.glob))
1256 else:
1263 else:
1257 yield (astyle.style_default, repr(self))
1264 yield (astyle.style_default, repr(self))
1258
1265
1259 def __repr__(self):
1266 def __repr__(self):
1260 return "%s.%s(%r)" % \
1267 return "%s.%s(%r)" % \
1261 (self.__class__.__module__, self.__class__.__name__, self.glob)
1268 (self.__class__.__module__, self.__class__.__name__, self.glob)
1262
1269
1263
1270
1264 class iwalk(Table):
1271 class iwalk(Table):
1265 """
1272 """
1266 List all files and directories in a directory and it's subdirectory.
1273 List all files and directories in a directory and it's subdirectory::
1267
1274
1268 >>> iwalk
1275 >>> iwalk
1269 >>> iwalk("/usr/local/lib/python2.4")
1276 >>> iwalk("/usr/local/lib/python2.4")
1270 >>> iwalk("~")
1277 >>> iwalk("~")
1271 """
1278 """
1272 def __init__(self, base=os.curdir, dirs=True, files=True):
1279 def __init__(self, base=os.curdir, dirs=True, files=True):
1273 self.base = os.path.expanduser(base)
1280 self.base = os.path.expanduser(base)
1274 self.dirs = dirs
1281 self.dirs = dirs
1275 self.files = files
1282 self.files = files
1276
1283
1277 def __iter__(self):
1284 def __iter__(self):
1278 for (dirpath, dirnames, filenames) in os.walk(self.base):
1285 for (dirpath, dirnames, filenames) in os.walk(self.base):
1279 if self.dirs:
1286 if self.dirs:
1280 for name in sorted(dirnames):
1287 for name in sorted(dirnames):
1281 yield ifile(os.path.join(dirpath, name))
1288 yield ifile(os.path.join(dirpath, name))
1282 if self.files:
1289 if self.files:
1283 for name in sorted(filenames):
1290 for name in sorted(filenames):
1284 yield ifile(os.path.join(dirpath, name))
1291 yield ifile(os.path.join(dirpath, name))
1285
1292
1286 def __xrepr__(self, mode="default"):
1293 def __xrepr__(self, mode="default"):
1287 if mode == "header" or mode == "footer" or mode == "cell":
1294 if mode == "header" or mode == "footer" or mode == "cell":
1288 yield (astyle.style_default,
1295 yield (astyle.style_default,
1289 "%s(%r)" % (self.__class__.__name__, self.base))
1296 "%s(%r)" % (self.__class__.__name__, self.base))
1290 else:
1297 else:
1291 yield (astyle.style_default, repr(self))
1298 yield (astyle.style_default, repr(self))
1292
1299
1293 def __repr__(self):
1300 def __repr__(self):
1294 return "%s.%s(%r)" % \
1301 return "%s.%s(%r)" % \
1295 (self.__class__.__module__, self.__class__.__name__, self.base)
1302 (self.__class__.__module__, self.__class__.__name__, self.base)
1296
1303
1297
1304
1298 class ipwdentry(object):
1305 class ipwdentry(object):
1299 """
1306 """
1300 ``ipwdentry`` objects encapsulate entries in the Unix user account and
1307 ``ipwdentry`` objects encapsulate entries in the Unix user account and
1301 password database.
1308 password database.
1302 """
1309 """
1303 def __init__(self, id):
1310 def __init__(self, id):
1304 self._id = id
1311 self._id = id
1305 self._entry = None
1312 self._entry = None
1306
1313
1307 def __eq__(self, other):
1314 def __eq__(self, other):
1308 return self.__class__ is other.__class__ and self._id == other._id
1315 return self.__class__ is other.__class__ and self._id == other._id
1309
1316
1310 def __ne__(self, other):
1317 def __ne__(self, other):
1311 return self.__class__ is not other.__class__ or self._id != other._id
1318 return self.__class__ is not other.__class__ or self._id != other._id
1312
1319
1313 def _getentry(self):
1320 def _getentry(self):
1314 if self._entry is None:
1321 if self._entry is None:
1315 if isinstance(self._id, basestring):
1322 if isinstance(self._id, basestring):
1316 self._entry = pwd.getpwnam(self._id)
1323 self._entry = pwd.getpwnam(self._id)
1317 else:
1324 else:
1318 self._entry = pwd.getpwuid(self._id)
1325 self._entry = pwd.getpwuid(self._id)
1319 return self._entry
1326 return self._entry
1320
1327
1321 def getname(self):
1328 def getname(self):
1322 if isinstance(self._id, basestring):
1329 if isinstance(self._id, basestring):
1323 return self._id
1330 return self._id
1324 else:
1331 else:
1325 return self._getentry().pw_name
1332 return self._getentry().pw_name
1326 name = property(getname, None, None, "User name")
1333 name = property(getname, None, None, "User name")
1327
1334
1328 def getpasswd(self):
1335 def getpasswd(self):
1329 return self._getentry().pw_passwd
1336 return self._getentry().pw_passwd
1330 passwd = property(getpasswd, None, None, "Password")
1337 passwd = property(getpasswd, None, None, "Password")
1331
1338
1332 def getuid(self):
1339 def getuid(self):
1333 if isinstance(self._id, basestring):
1340 if isinstance(self._id, basestring):
1334 return self._getentry().pw_uid
1341 return self._getentry().pw_uid
1335 else:
1342 else:
1336 return self._id
1343 return self._id
1337 uid = property(getuid, None, None, "User id")
1344 uid = property(getuid, None, None, "User id")
1338
1345
1339 def getgid(self):
1346 def getgid(self):
1340 return self._getentry().pw_gid
1347 return self._getentry().pw_gid
1341 gid = property(getgid, None, None, "Primary group id")
1348 gid = property(getgid, None, None, "Primary group id")
1342
1349
1343 def getgroup(self):
1350 def getgroup(self):
1344 return igrpentry(self.gid)
1351 return igrpentry(self.gid)
1345 group = property(getgroup, None, None, "Group")
1352 group = property(getgroup, None, None, "Group")
1346
1353
1347 def getgecos(self):
1354 def getgecos(self):
1348 return self._getentry().pw_gecos
1355 return self._getentry().pw_gecos
1349 gecos = property(getgecos, None, None, "Information (e.g. full user name)")
1356 gecos = property(getgecos, None, None, "Information (e.g. full user name)")
1350
1357
1351 def getdir(self):
1358 def getdir(self):
1352 return self._getentry().pw_dir
1359 return self._getentry().pw_dir
1353 dir = property(getdir, None, None, "$HOME directory")
1360 dir = property(getdir, None, None, "$HOME directory")
1354
1361
1355 def getshell(self):
1362 def getshell(self):
1356 return self._getentry().pw_shell
1363 return self._getentry().pw_shell
1357 shell = property(getshell, None, None, "Login shell")
1364 shell = property(getshell, None, None, "Login shell")
1358
1365
1359 def __xattrs__(self, mode="default"):
1366 def __xattrs__(self, mode="default"):
1360 return ("name", "passwd", "uid", "gid", "gecos", "dir", "shell")
1367 return ("name", "passwd", "uid", "gid", "gecos", "dir", "shell")
1361
1368
1362 def __repr__(self):
1369 def __repr__(self):
1363 return "%s.%s(%r)" % \
1370 return "%s.%s(%r)" % \
1364 (self.__class__.__module__, self.__class__.__name__, self._id)
1371 (self.__class__.__module__, self.__class__.__name__, self._id)
1365
1372
1366
1373
1367 class ipwd(Table):
1374 class ipwd(Table):
1368 """
1375 """
1369 List all entries in the Unix user account and password database.
1376 List all entries in the Unix user account and password database.
1370
1377
1371 Example:
1378 Example::
1372
1379
1373 >>> ipwd | isort("uid")
1380 >>> ipwd | isort("uid")
1374 """
1381 """
1375 def __iter__(self):
1382 def __iter__(self):
1376 for entry in pwd.getpwall():
1383 for entry in pwd.getpwall():
1377 yield ipwdentry(entry.pw_name)
1384 yield ipwdentry(entry.pw_name)
1378
1385
1379 def __xrepr__(self, mode="default"):
1386 def __xrepr__(self, mode="default"):
1380 if mode == "header" or mode == "footer" or mode == "cell":
1387 if mode == "header" or mode == "footer" or mode == "cell":
1381 yield (astyle.style_default, "%s()" % self.__class__.__name__)
1388 yield (astyle.style_default, "%s()" % self.__class__.__name__)
1382 else:
1389 else:
1383 yield (astyle.style_default, repr(self))
1390 yield (astyle.style_default, repr(self))
1384
1391
1385
1392
1386 class igrpentry(object):
1393 class igrpentry(object):
1387 """
1394 """
1388 ``igrpentry`` objects encapsulate entries in the Unix group database.
1395 ``igrpentry`` objects encapsulate entries in the Unix group database.
1389 """
1396 """
1390 def __init__(self, id):
1397 def __init__(self, id):
1391 self._id = id
1398 self._id = id
1392 self._entry = None
1399 self._entry = None
1393
1400
1394 def __eq__(self, other):
1401 def __eq__(self, other):
1395 return self.__class__ is other.__class__ and self._id == other._id
1402 return self.__class__ is other.__class__ and self._id == other._id
1396
1403
1397 def __ne__(self, other):
1404 def __ne__(self, other):
1398 return self.__class__ is not other.__class__ or self._id != other._id
1405 return self.__class__ is not other.__class__ or self._id != other._id
1399
1406
1400 def _getentry(self):
1407 def _getentry(self):
1401 if self._entry is None:
1408 if self._entry is None:
1402 if isinstance(self._id, basestring):
1409 if isinstance(self._id, basestring):
1403 self._entry = grp.getgrnam(self._id)
1410 self._entry = grp.getgrnam(self._id)
1404 else:
1411 else:
1405 self._entry = grp.getgrgid(self._id)
1412 self._entry = grp.getgrgid(self._id)
1406 return self._entry
1413 return self._entry
1407
1414
1408 def getname(self):
1415 def getname(self):
1409 if isinstance(self._id, basestring):
1416 if isinstance(self._id, basestring):
1410 return self._id
1417 return self._id
1411 else:
1418 else:
1412 return self._getentry().gr_name
1419 return self._getentry().gr_name
1413 name = property(getname, None, None, "Group name")
1420 name = property(getname, None, None, "Group name")
1414
1421
1415 def getpasswd(self):
1422 def getpasswd(self):
1416 return self._getentry().gr_passwd
1423 return self._getentry().gr_passwd
1417 passwd = property(getpasswd, None, None, "Password")
1424 passwd = property(getpasswd, None, None, "Password")
1418
1425
1419 def getgid(self):
1426 def getgid(self):
1420 if isinstance(self._id, basestring):
1427 if isinstance(self._id, basestring):
1421 return self._getentry().gr_gid
1428 return self._getentry().gr_gid
1422 else:
1429 else:
1423 return self._id
1430 return self._id
1424 gid = property(getgid, None, None, "Group id")
1431 gid = property(getgid, None, None, "Group id")
1425
1432
1426 def getmem(self):
1433 def getmem(self):
1427 return self._getentry().gr_mem
1434 return self._getentry().gr_mem
1428 mem = property(getmem, None, None, "Members")
1435 mem = property(getmem, None, None, "Members")
1429
1436
1430 def __xattrs__(self, mode="default"):
1437 def __xattrs__(self, mode="default"):
1431 return ("name", "passwd", "gid", "mem")
1438 return ("name", "passwd", "gid", "mem")
1432
1439
1433 def __xrepr__(self, mode="default"):
1440 def __xrepr__(self, mode="default"):
1434 if mode == "header" or mode == "footer" or mode == "cell":
1441 if mode == "header" or mode == "footer" or mode == "cell":
1435 yield (astyle.style_default, "group ")
1442 yield (astyle.style_default, "group ")
1436 try:
1443 try:
1437 yield (astyle.style_default, self.name)
1444 yield (astyle.style_default, self.name)
1438 except KeyError:
1445 except KeyError:
1439 if isinstance(self._id, basestring):
1446 if isinstance(self._id, basestring):
1440 yield (astyle.style_default, self.name_id)
1447 yield (astyle.style_default, self.name_id)
1441 else:
1448 else:
1442 yield (astyle.style_type_number, str(self._id))
1449 yield (astyle.style_type_number, str(self._id))
1443 else:
1450 else:
1444 yield (astyle.style_default, repr(self))
1451 yield (astyle.style_default, repr(self))
1445
1452
1446 def __iter__(self):
1453 def __iter__(self):
1447 for member in self.mem:
1454 for member in self.mem:
1448 yield ipwdentry(member)
1455 yield ipwdentry(member)
1449
1456
1450 def __repr__(self):
1457 def __repr__(self):
1451 return "%s.%s(%r)" % \
1458 return "%s.%s(%r)" % \
1452 (self.__class__.__module__, self.__class__.__name__, self._id)
1459 (self.__class__.__module__, self.__class__.__name__, self._id)
1453
1460
1454
1461
1455 class igrp(Table):
1462 class igrp(Table):
1456 """
1463 """
1457 This ``Table`` lists all entries in the Unix group database.
1464 This ``Table`` lists all entries in the Unix group database.
1458 """
1465 """
1459 def __iter__(self):
1466 def __iter__(self):
1460 for entry in grp.getgrall():
1467 for entry in grp.getgrall():
1461 yield igrpentry(entry.gr_name)
1468 yield igrpentry(entry.gr_name)
1462
1469
1463 def __xrepr__(self, mode="default"):
1470 def __xrepr__(self, mode="default"):
1464 if mode == "header" or mode == "footer":
1471 if mode == "header" or mode == "footer":
1465 yield (astyle.style_default, "%s()" % self.__class__.__name__)
1472 yield (astyle.style_default, "%s()" % self.__class__.__name__)
1466 else:
1473 else:
1467 yield (astyle.style_default, repr(self))
1474 yield (astyle.style_default, repr(self))
1468
1475
1469
1476
1470 class Fields(object):
1477 class Fields(object):
1471 def __init__(self, fieldnames, **fields):
1478 def __init__(self, fieldnames, **fields):
1472 self.__fieldnames = [upgradexattr(fieldname) for fieldname in fieldnames]
1479 self.__fieldnames = [upgradexattr(fieldname) for fieldname in fieldnames]
1473 for (key, value) in fields.iteritems():
1480 for (key, value) in fields.iteritems():
1474 setattr(self, key, value)
1481 setattr(self, key, value)
1475
1482
1476 def __xattrs__(self, mode="default"):
1483 def __xattrs__(self, mode="default"):
1477 return self.__fieldnames
1484 return self.__fieldnames
1478
1485
1479 def __xrepr__(self, mode="default"):
1486 def __xrepr__(self, mode="default"):
1480 yield (-1, False)
1487 yield (-1, False)
1481 if mode == "header" or mode == "cell":
1488 if mode == "header" or mode == "cell":
1482 yield (astyle.style_default, self.__class__.__name__)
1489 yield (astyle.style_default, self.__class__.__name__)
1483 yield (astyle.style_default, "(")
1490 yield (astyle.style_default, "(")
1484 for (i, f) in enumerate(self.__fieldnames):
1491 for (i, f) in enumerate(self.__fieldnames):
1485 if i:
1492 if i:
1486 yield (astyle.style_default, ", ")
1493 yield (astyle.style_default, ", ")
1487 yield (astyle.style_default, f.name())
1494 yield (astyle.style_default, f.name())
1488 yield (astyle.style_default, "=")
1495 yield (astyle.style_default, "=")
1489 for part in xrepr(getattr(self, f), "default"):
1496 for part in xrepr(getattr(self, f), "default"):
1490 yield part
1497 yield part
1491 yield (astyle.style_default, ")")
1498 yield (astyle.style_default, ")")
1492 elif mode == "footer":
1499 elif mode == "footer":
1493 yield (astyle.style_default, self.__class__.__name__)
1500 yield (astyle.style_default, self.__class__.__name__)
1494 yield (astyle.style_default, "(")
1501 yield (astyle.style_default, "(")
1495 for (i, f) in enumerate(self.__fieldnames):
1502 for (i, f) in enumerate(self.__fieldnames):
1496 if i:
1503 if i:
1497 yield (astyle.style_default, ", ")
1504 yield (astyle.style_default, ", ")
1498 yield (astyle.style_default, f.name())
1505 yield (astyle.style_default, f.name())
1499 yield (astyle.style_default, ")")
1506 yield (astyle.style_default, ")")
1500 else:
1507 else:
1501 yield (astyle.style_default, repr(self))
1508 yield (astyle.style_default, repr(self))
1502
1509
1503
1510
1504 class FieldTable(Table, list):
1511 class FieldTable(Table, list):
1505 def __init__(self, *fields):
1512 def __init__(self, *fields):
1506 Table.__init__(self)
1513 Table.__init__(self)
1507 list.__init__(self)
1514 list.__init__(self)
1508 self.fields = fields
1515 self.fields = fields
1509
1516
1510 def add(self, **fields):
1517 def add(self, **fields):
1511 self.append(Fields(self.fields, **fields))
1518 self.append(Fields(self.fields, **fields))
1512
1519
1513 def __xrepr__(self, mode="default"):
1520 def __xrepr__(self, mode="default"):
1514 yield (-1, False)
1521 yield (-1, False)
1515 if mode == "header" or mode == "footer":
1522 if mode == "header" or mode == "footer":
1516 yield (astyle.style_default, self.__class__.__name__)
1523 yield (astyle.style_default, self.__class__.__name__)
1517 yield (astyle.style_default, "(")
1524 yield (astyle.style_default, "(")
1518 for (i, f) in enumerate(self.__fieldnames):
1525 for (i, f) in enumerate(self.__fieldnames):
1519 if i:
1526 if i:
1520 yield (astyle.style_default, ", ")
1527 yield (astyle.style_default, ", ")
1521 yield (astyle.style_default, f)
1528 yield (astyle.style_default, f)
1522 yield (astyle.style_default, ")")
1529 yield (astyle.style_default, ")")
1523 else:
1530 else:
1524 yield (astyle.style_default, repr(self))
1531 yield (astyle.style_default, repr(self))
1525
1532
1526 def __repr__(self):
1533 def __repr__(self):
1527 return "<%s.%s object with fields=%r at 0x%x>" % \
1534 return "<%s.%s object with fields=%r at 0x%x>" % \
1528 (self.__class__.__module__, self.__class__.__name__,
1535 (self.__class__.__module__, self.__class__.__name__,
1529 ", ".join(map(repr, self.fields)), id(self))
1536 ", ".join(map(repr, self.fields)), id(self))
1530
1537
1531
1538
1532 class List(list):
1539 class List(list):
1533 def __xattrs__(self, mode="default"):
1540 def __xattrs__(self, mode="default"):
1534 return xrange(len(self))
1541 return xrange(len(self))
1535
1542
1536 def __xrepr__(self, mode="default"):
1543 def __xrepr__(self, mode="default"):
1537 yield (-1, False)
1544 yield (-1, False)
1538 if mode == "header" or mode == "cell" or mode == "footer" or mode == "default":
1545 if mode == "header" or mode == "cell" or mode == "footer" or mode == "default":
1539 yield (astyle.style_default, self.__class__.__name__)
1546 yield (astyle.style_default, self.__class__.__name__)
1540 yield (astyle.style_default, "(")
1547 yield (astyle.style_default, "(")
1541 for (i, item) in enumerate(self):
1548 for (i, item) in enumerate(self):
1542 if i:
1549 if i:
1543 yield (astyle.style_default, ", ")
1550 yield (astyle.style_default, ", ")
1544 for part in xrepr(item, "default"):
1551 for part in xrepr(item, "default"):
1545 yield part
1552 yield part
1546 yield (astyle.style_default, ")")
1553 yield (astyle.style_default, ")")
1547 else:
1554 else:
1548 yield (astyle.style_default, repr(self))
1555 yield (astyle.style_default, repr(self))
1549
1556
1550
1557
1551 class ienv(Table):
1558 class ienv(Table):
1552 """
1559 """
1553 List environment variables.
1560 List environment variables.
1554
1561
1555 Example:
1562 Example::
1556
1563
1557 >>> ienv
1564 >>> ienv
1558 """
1565 """
1559
1566
1560 def __iter__(self):
1567 def __iter__(self):
1561 fields = ("key", "value")
1568 fields = ("key", "value")
1562 for (key, value) in os.environ.iteritems():
1569 for (key, value) in os.environ.iteritems():
1563 yield Fields(fields, key=key, value=value)
1570 yield Fields(fields, key=key, value=value)
1564
1571
1565 def __xrepr__(self, mode="default"):
1572 def __xrepr__(self, mode="default"):
1566 if mode == "header" or mode == "cell":
1573 if mode == "header" or mode == "cell":
1567 yield (astyle.style_default, "%s()" % self.__class__.__name__)
1574 yield (astyle.style_default, "%s()" % self.__class__.__name__)
1568 else:
1575 else:
1569 yield (astyle.style_default, repr(self))
1576 yield (astyle.style_default, repr(self))
1570
1577
1571
1578
1572 class ihist(Table):
1579 class ihist(Table):
1573 """
1580 """
1574 IPython input history
1581 IPython input history
1575
1582
1576 Example:
1583 Example::
1577
1584
1578 >>> ihist
1585 >>> ihist
1579 >>> ihist(True) (raw mode)
1586 >>> ihist(True) (raw mode)
1580 """
1587 """
1581 def __init__(self, raw=True):
1588 def __init__(self, raw=True):
1582 self.raw = raw
1589 self.raw = raw
1583
1590
1584 def __iter__(self):
1591 def __iter__(self):
1585 api = ipapi.get()
1592 api = ipapi.get()
1586 if self.raw:
1593 if self.raw:
1587 for line in api.IP.input_hist_raw:
1594 for line in api.IP.input_hist_raw:
1588 yield line.rstrip("\n")
1595 yield line.rstrip("\n")
1589 else:
1596 else:
1590 for line in api.IP.input_hist:
1597 for line in api.IP.input_hist:
1591 yield line.rstrip("\n")
1598 yield line.rstrip("\n")
1592
1599
1593
1600
1594 class icsv(Pipe):
1601 class icsv(Pipe):
1595 """
1602 """
1596 This ``Pipe`` lists turn the input (with must be a pipe outputting lines
1603 This ``Pipe`` turns the input (with must be a pipe outputting lines
1597 or an ``ifile``) into lines of CVS columns.
1604 or an ``ifile``) into lines of CVS columns.
1598 """
1605 """
1599 def __init__(self, **csvargs):
1606 def __init__(self, **csvargs):
1600 """
1607 """
1601 Create an ``icsv`` object. ``cvsargs`` will be passed through as
1608 Create an ``icsv`` object. ``cvsargs`` will be passed through as
1602 keyword arguments to ``cvs.reader()``.
1609 keyword arguments to ``cvs.reader()``.
1603 """
1610 """
1604 self.csvargs = csvargs
1611 self.csvargs = csvargs
1605
1612
1606 def __iter__(self):
1613 def __iter__(self):
1607 input = self.input
1614 input = self.input
1608 if isinstance(input, ifile):
1615 if isinstance(input, ifile):
1609 input = input.open("rb")
1616 input = input.open("rb")
1610 reader = csv.reader(input, **self.csvargs)
1617 reader = csv.reader(input, **self.csvargs)
1611 for line in reader:
1618 for line in reader:
1612 yield List(line)
1619 yield List(line)
1613
1620
1614 def __xrepr__(self, mode="default"):
1621 def __xrepr__(self, mode="default"):
1615 yield (-1, False)
1622 yield (-1, False)
1616 if mode == "header" or mode == "footer":
1623 if mode == "header" or mode == "footer":
1617 input = getattr(self, "input", None)
1624 input = getattr(self, "input", None)
1618 if input is not None:
1625 if input is not None:
1619 for part in xrepr(input, mode):
1626 for part in xrepr(input, mode):
1620 yield part
1627 yield part
1621 yield (astyle.style_default, " | ")
1628 yield (astyle.style_default, " | ")
1622 yield (astyle.style_default, "%s(" % self.__class__.__name__)
1629 yield (astyle.style_default, "%s(" % self.__class__.__name__)
1623 for (i, (name, value)) in enumerate(self.csvargs.iteritems()):
1630 for (i, (name, value)) in enumerate(self.csvargs.iteritems()):
1624 if i:
1631 if i:
1625 yield (astyle.style_default, ", ")
1632 yield (astyle.style_default, ", ")
1626 yield (astyle.style_default, name)
1633 yield (astyle.style_default, name)
1627 yield (astyle.style_default, "=")
1634 yield (astyle.style_default, "=")
1628 for part in xrepr(value, "default"):
1635 for part in xrepr(value, "default"):
1629 yield part
1636 yield part
1630 yield (astyle.style_default, ")")
1637 yield (astyle.style_default, ")")
1631 else:
1638 else:
1632 yield (astyle.style_default, repr(self))
1639 yield (astyle.style_default, repr(self))
1633
1640
1634 def __repr__(self):
1641 def __repr__(self):
1635 args = ", ".join(["%s=%r" % item for item in self.csvargs.iteritems()])
1642 args = ", ".join(["%s=%r" % item for item in self.csvargs.iteritems()])
1636 return "<%s.%s %s at 0x%x>" % \
1643 return "<%s.%s %s at 0x%x>" % \
1637 (self.__class__.__module__, self.__class__.__name__, args, id(self))
1644 (self.__class__.__module__, self.__class__.__name__, args, id(self))
1638
1645
1639
1646
1640 class ix(Table):
1647 class ix(Table):
1641 """
1648 """
1642 Execute a system command and list its output as lines
1649 Execute a system command and list its output as lines
1643 (similar to ``os.popen()``).
1650 (similar to ``os.popen()``).
1644
1651
1645 Examples:
1652 Examples::
1646
1653
1647 >>> ix("ps x")
1654 >>> ix("ps x")
1648 >>> ix("find .") | ifile
1655 >>> ix("find .") | ifile
1649 """
1656 """
1650 def __init__(self, cmd):
1657 def __init__(self, cmd):
1651 self.cmd = cmd
1658 self.cmd = cmd
1652 self._pipeout = None
1659 self._pipeout = None
1653
1660
1654 def __iter__(self):
1661 def __iter__(self):
1655 (_pipein, self._pipeout) = os.popen4(self.cmd)
1662 (_pipein, self._pipeout) = os.popen4(self.cmd)
1656 _pipein.close()
1663 _pipein.close()
1657 for l in self._pipeout:
1664 for l in self._pipeout:
1658 yield l.rstrip("\r\n")
1665 yield l.rstrip("\r\n")
1659 self._pipeout.close()
1666 self._pipeout.close()
1660 self._pipeout = None
1667 self._pipeout = None
1661
1668
1662 def __del__(self):
1669 def __del__(self):
1663 if self._pipeout is not None and not self._pipeout.closed:
1670 if self._pipeout is not None and not self._pipeout.closed:
1664 self._pipeout.close()
1671 self._pipeout.close()
1665 self._pipeout = None
1672 self._pipeout = None
1666
1673
1667 def __xrepr__(self, mode="default"):
1674 def __xrepr__(self, mode="default"):
1668 if mode == "header" or mode == "footer":
1675 if mode == "header" or mode == "footer":
1669 yield (astyle.style_default,
1676 yield (astyle.style_default,
1670 "%s(%r)" % (self.__class__.__name__, self.cmd))
1677 "%s(%r)" % (self.__class__.__name__, self.cmd))
1671 else:
1678 else:
1672 yield (astyle.style_default, repr(self))
1679 yield (astyle.style_default, repr(self))
1673
1680
1674 def __repr__(self):
1681 def __repr__(self):
1675 return "%s.%s(%r)" % \
1682 return "%s.%s(%r)" % \
1676 (self.__class__.__module__, self.__class__.__name__, self.cmd)
1683 (self.__class__.__module__, self.__class__.__name__, self.cmd)
1677
1684
1678
1685
1679 class ifilter(Pipe):
1686 class ifilter(Pipe):
1680 """
1687 """
1681 Filter an input pipe. Only objects where an expression evaluates to true
1688 Filter an input pipe. Only objects where an expression evaluates to true
1682 (and doesn't raise an exception) are listed.
1689 (and doesn't raise an exception) are listed.
1683
1690
1684 Examples:
1691 Examples::
1685
1692
1686 >>> ils | ifilter("_.isfile() and size>1000")
1693 >>> ils | ifilter("_.isfile() and size>1000")
1687 >>> igrp | ifilter("len(mem)")
1694 >>> igrp | ifilter("len(mem)")
1688 >>> sys.modules | ifilter(lambda _:_.value is not None)
1695 >>> sys.modules | ifilter(lambda _:_.value is not None)
1689 """
1696 """
1690
1697
1691 def __init__(self, expr, globals=None, errors="raiseifallfail"):
1698 def __init__(self, expr, globals=None, errors="raiseifallfail"):
1692 """
1699 """
1693 Create an ``ifilter`` object. ``expr`` can be a callable or a string
1700 Create an ``ifilter`` object. ``expr`` can be a callable or a string
1694 containing an expression. ``globals`` will be used as the global
1701 containing an expression. ``globals`` will be used as the global
1695 namespace for calling string expressions (defaulting to IPython's
1702 namespace for calling string expressions (defaulting to IPython's
1696 user namespace). ``errors`` specifies how exception during evaluation
1703 user namespace). ``errors`` specifies how exception during evaluation
1697 of ``expr`` are handled:
1704 of ``expr`` are handled:
1698
1705
1699 * ``drop``: drop all items that have errors;
1706 ``"drop"``
1707 drop all items that have errors;
1700
1708
1701 * ``keep``: keep all items that have errors;
1709 ``"keep"``
1710 keep all items that have errors;
1702
1711
1703 * ``keeperror``: keep the exception of all items that have errors;
1712 ``"keeperror"``
1713 keep the exception of all items that have errors;
1704
1714
1705 * ``raise``: raise the exception;
1715 ``"raise"``
1716 raise the exception;
1706
1717
1707 * ``raiseifallfail``: raise the first exception if all items have errors;
1718 ``"raiseifallfail"``
1708 otherwise drop those with errors (this is the default).
1719 raise the first exception if all items have errors; otherwise drop
1720 those with errors (this is the default).
1709 """
1721 """
1710 self.expr = expr
1722 self.expr = expr
1711 self.globals = globals
1723 self.globals = globals
1712 self.errors = errors
1724 self.errors = errors
1713
1725
1714 def __iter__(self):
1726 def __iter__(self):
1715 if callable(self.expr):
1727 if callable(self.expr):
1716 test = self.expr
1728 test = self.expr
1717 else:
1729 else:
1718 g = getglobals(self.globals)
1730 g = getglobals(self.globals)
1719 expr = compile(self.expr, "ipipe-expression", "eval")
1731 expr = compile(self.expr, "ipipe-expression", "eval")
1720 def test(item):
1732 def test(item):
1721 return eval(expr, g, AttrNamespace(item))
1733 return eval(expr, g, AttrNamespace(item))
1722
1734
1723 ok = 0
1735 ok = 0
1724 exc_info = None
1736 exc_info = None
1725 for item in xiter(self.input):
1737 for item in xiter(self.input):
1726 try:
1738 try:
1727 if test(item):
1739 if test(item):
1728 yield item
1740 yield item
1729 ok += 1
1741 ok += 1
1730 except (KeyboardInterrupt, SystemExit):
1742 except (KeyboardInterrupt, SystemExit):
1731 raise
1743 raise
1732 except Exception, exc:
1744 except Exception, exc:
1733 if self.errors == "drop":
1745 if self.errors == "drop":
1734 pass # Ignore errors
1746 pass # Ignore errors
1735 elif self.errors == "keep":
1747 elif self.errors == "keep":
1736 yield item
1748 yield item
1737 elif self.errors == "keeperror":
1749 elif self.errors == "keeperror":
1738 yield exc
1750 yield exc
1739 elif self.errors == "raise":
1751 elif self.errors == "raise":
1740 raise
1752 raise
1741 elif self.errors == "raiseifallfail":
1753 elif self.errors == "raiseifallfail":
1742 if exc_info is None:
1754 if exc_info is None:
1743 exc_info = sys.exc_info()
1755 exc_info = sys.exc_info()
1744 if not ok and exc_info is not None:
1756 if not ok and exc_info is not None:
1745 raise exc_info[0], exc_info[1], exc_info[2]
1757 raise exc_info[0], exc_info[1], exc_info[2]
1746
1758
1747 def __xrepr__(self, mode="default"):
1759 def __xrepr__(self, mode="default"):
1748 if mode == "header" or mode == "footer":
1760 if mode == "header" or mode == "footer":
1749 input = getattr(self, "input", None)
1761 input = getattr(self, "input", None)
1750 if input is not None:
1762 if input is not None:
1751 for part in xrepr(input, mode):
1763 for part in xrepr(input, mode):
1752 yield part
1764 yield part
1753 yield (astyle.style_default, " | ")
1765 yield (astyle.style_default, " | ")
1754 yield (astyle.style_default, "%s(" % self.__class__.__name__)
1766 yield (astyle.style_default, "%s(" % self.__class__.__name__)
1755 for part in xrepr(self.expr, "default"):
1767 for part in xrepr(self.expr, "default"):
1756 yield part
1768 yield part
1757 yield (astyle.style_default, ")")
1769 yield (astyle.style_default, ")")
1758 else:
1770 else:
1759 yield (astyle.style_default, repr(self))
1771 yield (astyle.style_default, repr(self))
1760
1772
1761 def __repr__(self):
1773 def __repr__(self):
1762 return "<%s.%s expr=%r at 0x%x>" % \
1774 return "<%s.%s expr=%r at 0x%x>" % \
1763 (self.__class__.__module__, self.__class__.__name__,
1775 (self.__class__.__module__, self.__class__.__name__,
1764 self.expr, id(self))
1776 self.expr, id(self))
1765
1777
1766
1778
1767 class ieval(Pipe):
1779 class ieval(Pipe):
1768 """
1780 """
1769 Evaluate an expression for each object in the input pipe.
1781 Evaluate an expression for each object in the input pipe.
1770
1782
1771 Examples:
1783 Examples::
1772
1784
1773 >>> ils | ieval("_.abspath()")
1785 >>> ils | ieval("_.abspath()")
1774 >>> sys.path | ieval(ifile)
1786 >>> sys.path | ieval(ifile)
1775 """
1787 """
1776
1788
1777 def __init__(self, expr, globals=None, errors="raiseifallfail"):
1789 def __init__(self, expr, globals=None, errors="raiseifallfail"):
1778 """
1790 """
1779 Create an ``ieval`` object. ``expr`` can be a callable or a string
1791 Create an ``ieval`` object. ``expr`` can be a callable or a string
1780 containing an expression. For the meaning of ``globals`` and
1792 containing an expression. For the meaning of ``globals`` and
1781 ``errors`` see ``ifilter``.
1793 ``errors`` see ``ifilter``.
1782 """
1794 """
1783 self.expr = expr
1795 self.expr = expr
1784 self.globals = globals
1796 self.globals = globals
1785 self.errors = errors
1797 self.errors = errors
1786
1798
1787 def __iter__(self):
1799 def __iter__(self):
1788 if callable(self.expr):
1800 if callable(self.expr):
1789 do = self.expr
1801 do = self.expr
1790 else:
1802 else:
1791 g = getglobals(self.globals)
1803 g = getglobals(self.globals)
1792 expr = compile(self.expr, "ipipe-expression", "eval")
1804 expr = compile(self.expr, "ipipe-expression", "eval")
1793 def do(item):
1805 def do(item):
1794 return eval(expr, g, AttrNamespace(item))
1806 return eval(expr, g, AttrNamespace(item))
1795
1807
1796 ok = 0
1808 ok = 0
1797 exc_info = None
1809 exc_info = None
1798 for item in xiter(self.input):
1810 for item in xiter(self.input):
1799 try:
1811 try:
1800 yield do(item)
1812 yield do(item)
1801 except (KeyboardInterrupt, SystemExit):
1813 except (KeyboardInterrupt, SystemExit):
1802 raise
1814 raise
1803 except Exception, exc:
1815 except Exception, exc:
1804 if self.errors == "drop":
1816 if self.errors == "drop":
1805 pass # Ignore errors
1817 pass # Ignore errors
1806 elif self.errors == "keep":
1818 elif self.errors == "keep":
1807 yield item
1819 yield item
1808 elif self.errors == "keeperror":
1820 elif self.errors == "keeperror":
1809 yield exc
1821 yield exc
1810 elif self.errors == "raise":
1822 elif self.errors == "raise":
1811 raise
1823 raise
1812 elif self.errors == "raiseifallfail":
1824 elif self.errors == "raiseifallfail":
1813 if exc_info is None:
1825 if exc_info is None:
1814 exc_info = sys.exc_info()
1826 exc_info = sys.exc_info()
1815 if not ok and exc_info is not None:
1827 if not ok and exc_info is not None:
1816 raise exc_info[0], exc_info[1], exc_info[2]
1828 raise exc_info[0], exc_info[1], exc_info[2]
1817
1829
1818 def __xrepr__(self, mode="default"):
1830 def __xrepr__(self, mode="default"):
1819 if mode == "header" or mode == "footer":
1831 if mode == "header" or mode == "footer":
1820 input = getattr(self, "input", None)
1832 input = getattr(self, "input", None)
1821 if input is not None:
1833 if input is not None:
1822 for part in xrepr(input, mode):
1834 for part in xrepr(input, mode):
1823 yield part
1835 yield part
1824 yield (astyle.style_default, " | ")
1836 yield (astyle.style_default, " | ")
1825 yield (astyle.style_default, "%s(" % self.__class__.__name__)
1837 yield (astyle.style_default, "%s(" % self.__class__.__name__)
1826 for part in xrepr(self.expr, "default"):
1838 for part in xrepr(self.expr, "default"):
1827 yield part
1839 yield part
1828 yield (astyle.style_default, ")")
1840 yield (astyle.style_default, ")")
1829 else:
1841 else:
1830 yield (astyle.style_default, repr(self))
1842 yield (astyle.style_default, repr(self))
1831
1843
1832 def __repr__(self):
1844 def __repr__(self):
1833 return "<%s.%s expr=%r at 0x%x>" % \
1845 return "<%s.%s expr=%r at 0x%x>" % \
1834 (self.__class__.__module__, self.__class__.__name__,
1846 (self.__class__.__module__, self.__class__.__name__,
1835 self.expr, id(self))
1847 self.expr, id(self))
1836
1848
1837
1849
1838 class ienum(Pipe):
1850 class ienum(Pipe):
1839 """
1851 """
1840 Enumerate the input pipe (i.e. wrap each input object in an object
1852 Enumerate the input pipe (i.e. wrap each input object in an object
1841 with ``index`` and ``object`` attributes).
1853 with ``index`` and ``object`` attributes).
1842
1854
1843 Examples:
1855 Examples::
1844
1856
1845 >>> xrange(20) | ieval("_,_*_") | ienum | ifilter("index % 2 == 0") | ieval("object")
1857 >>> xrange(20) | ieval("_,_*_") | ienum | ifilter("index % 2 == 0") | ieval("object")
1846 """
1858 """
1847 def __iter__(self):
1859 def __iter__(self):
1848 fields = ("index", "object")
1860 fields = ("index", "object")
1849 for (index, object) in enumerate(xiter(self.input)):
1861 for (index, object) in enumerate(xiter(self.input)):
1850 yield Fields(fields, index=index, object=object)
1862 yield Fields(fields, index=index, object=object)
1851
1863
1852
1864
1853 class isort(Pipe):
1865 class isort(Pipe):
1854 """
1866 """
1855 Sorts the input pipe.
1867 Sorts the input pipe.
1856
1868
1857 Examples:
1869 Examples::
1858
1870
1859 >>> ils | isort("size")
1871 >>> ils | isort("size")
1860 >>> ils | isort("_.isdir(), _.lower()", reverse=True)
1872 >>> ils | isort("_.isdir(), _.lower()", reverse=True)
1861 """
1873 """
1862
1874
1863 def __init__(self, key=None, globals=None, reverse=False):
1875 def __init__(self, key=None, globals=None, reverse=False):
1864 """
1876 """
1865 Create an ``isort`` object. ``key`` can be a callable or a string
1877 Create an ``isort`` object. ``key`` can be a callable or a string
1866 containing an expression (or ``None`` in which case the items
1878 containing an expression (or ``None`` in which case the items
1867 themselves will be sorted). If ``reverse`` is true the sort order
1879 themselves will be sorted). If ``reverse`` is true the sort order
1868 will be reversed. For the meaning of ``globals`` see ``ifilter``.
1880 will be reversed. For the meaning of ``globals`` see ``ifilter``.
1869 """
1881 """
1870 self.key = key
1882 self.key = key
1871 self.globals = globals
1883 self.globals = globals
1872 self.reverse = reverse
1884 self.reverse = reverse
1873
1885
1874 def __iter__(self):
1886 def __iter__(self):
1875 if self.key is None:
1887 if self.key is None:
1876 items = sorted(xiter(self.input), reverse=self.reverse)
1888 items = sorted(xiter(self.input), reverse=self.reverse)
1877 elif callable(self.key):
1889 elif callable(self.key):
1878 items = sorted(xiter(self.input), key=self.key, reverse=self.reverse)
1890 items = sorted(xiter(self.input), key=self.key, reverse=self.reverse)
1879 else:
1891 else:
1880 g = getglobals(self.globals)
1892 g = getglobals(self.globals)
1881 key = compile(self.key, "ipipe-expression", "eval")
1893 key = compile(self.key, "ipipe-expression", "eval")
1882 def realkey(item):
1894 def realkey(item):
1883 return eval(key, g, AttrNamespace(item))
1895 return eval(key, g, AttrNamespace(item))
1884 items = sorted(xiter(self.input), key=realkey, reverse=self.reverse)
1896 items = sorted(xiter(self.input), key=realkey, reverse=self.reverse)
1885 for item in items:
1897 for item in items:
1886 yield item
1898 yield item
1887
1899
1888 def __xrepr__(self, mode="default"):
1900 def __xrepr__(self, mode="default"):
1889 if mode == "header" or mode == "footer":
1901 if mode == "header" or mode == "footer":
1890 input = getattr(self, "input", None)
1902 input = getattr(self, "input", None)
1891 if input is not None:
1903 if input is not None:
1892 for part in xrepr(input, mode):
1904 for part in xrepr(input, mode):
1893 yield part
1905 yield part
1894 yield (astyle.style_default, " | ")
1906 yield (astyle.style_default, " | ")
1895 yield (astyle.style_default, "%s(" % self.__class__.__name__)
1907 yield (astyle.style_default, "%s(" % self.__class__.__name__)
1896 for part in xrepr(self.key, "default"):
1908 for part in xrepr(self.key, "default"):
1897 yield part
1909 yield part
1898 if self.reverse:
1910 if self.reverse:
1899 yield (astyle.style_default, ", ")
1911 yield (astyle.style_default, ", ")
1900 for part in xrepr(True, "default"):
1912 for part in xrepr(True, "default"):
1901 yield part
1913 yield part
1902 yield (astyle.style_default, ")")
1914 yield (astyle.style_default, ")")
1903 else:
1915 else:
1904 yield (astyle.style_default, repr(self))
1916 yield (astyle.style_default, repr(self))
1905
1917
1906 def __repr__(self):
1918 def __repr__(self):
1907 return "<%s.%s key=%r reverse=%r at 0x%x>" % \
1919 return "<%s.%s key=%r reverse=%r at 0x%x>" % \
1908 (self.__class__.__module__, self.__class__.__name__,
1920 (self.__class__.__module__, self.__class__.__name__,
1909 self.key, self.reverse, id(self))
1921 self.key, self.reverse, id(self))
1910
1922
1911
1923
1912 tab = 3 # for expandtabs()
1924 tab = 3 # for expandtabs()
1913
1925
1914 def _format(field):
1926 def _format(field):
1915 if isinstance(field, str):
1927 if isinstance(field, str):
1916 text = repr(field.expandtabs(tab))[1:-1]
1928 text = repr(field.expandtabs(tab))[1:-1]
1917 elif isinstance(field, unicode):
1929 elif isinstance(field, unicode):
1918 text = repr(field.expandtabs(tab))[2:-1]
1930 text = repr(field.expandtabs(tab))[2:-1]
1919 elif isinstance(field, datetime.datetime):
1931 elif isinstance(field, datetime.datetime):
1920 # Don't use strftime() here, as this requires year >= 1900
1932 # Don't use strftime() here, as this requires year >= 1900
1921 text = "%04d-%02d-%02d %02d:%02d:%02d.%06d" % \
1933 text = "%04d-%02d-%02d %02d:%02d:%02d.%06d" % \
1922 (field.year, field.month, field.day,
1934 (field.year, field.month, field.day,
1923 field.hour, field.minute, field.second, field.microsecond)
1935 field.hour, field.minute, field.second, field.microsecond)
1924 elif isinstance(field, datetime.date):
1936 elif isinstance(field, datetime.date):
1925 text = "%04d-%02d-%02d" % (field.year, field.month, field.day)
1937 text = "%04d-%02d-%02d" % (field.year, field.month, field.day)
1926 else:
1938 else:
1927 text = repr(field)
1939 text = repr(field)
1928 return text
1940 return text
1929
1941
1930
1942
1931 class Display(object):
1943 class Display(object):
1932 class __metaclass__(type):
1944 class __metaclass__(type):
1933 def __ror__(self, input):
1945 def __ror__(self, input):
1934 return input | self()
1946 return input | self()
1935
1947
1936 def __init__(self, input=None):
1948 def __init__(self, input=None):
1937 self.input = input
1949 self.input = input
1938
1950
1939 def __ror__(self, input):
1951 def __ror__(self, input):
1940 self.input = input
1952 self.input = input
1941 return self
1953 return self
1942
1954
1943 def display(self):
1955 def display(self):
1944 pass
1956 pass
1945
1957
1946
1958
1947 class iless(Display):
1959 class iless(Display):
1948 cmd = "less --quit-if-one-screen --LONG-PROMPT --LINE-NUMBERS --chop-long-lines --shift=8 --RAW-CONTROL-CHARS"
1960 cmd = "less --quit-if-one-screen --LONG-PROMPT --LINE-NUMBERS --chop-long-lines --shift=8 --RAW-CONTROL-CHARS"
1949
1961
1950 def display(self):
1962 def display(self):
1951 try:
1963 try:
1952 pager = os.popen(self.cmd, "w")
1964 pager = os.popen(self.cmd, "w")
1953 try:
1965 try:
1954 for item in xiter(self.input):
1966 for item in xiter(self.input):
1955 first = False
1967 first = False
1956 for attr in xattrs(item, "default"):
1968 for attr in xattrs(item, "default"):
1957 if first:
1969 if first:
1958 first = False
1970 first = False
1959 else:
1971 else:
1960 pager.write(" ")
1972 pager.write(" ")
1961 attr = upgradexattr(attr)
1973 attr = upgradexattr(attr)
1962 if not isinstance(attr, SelfDescriptor):
1974 if not isinstance(attr, SelfDescriptor):
1963 pager.write(attr.name())
1975 pager.write(attr.name())
1964 pager.write("=")
1976 pager.write("=")
1965 pager.write(str(attr.value(item)))
1977 pager.write(str(attr.value(item)))
1966 pager.write("\n")
1978 pager.write("\n")
1967 finally:
1979 finally:
1968 pager.close()
1980 pager.close()
1969 except Exception, exc:
1981 except Exception, exc:
1970 print "%s: %s" % (exc.__class__.__name__, str(exc))
1982 print "%s: %s" % (exc.__class__.__name__, str(exc))
1971
1983
1972
1984
1973 class _RedirectIO(object):
1985 class _RedirectIO(object):
1974 def __init__(self,*args,**kwargs):
1986 def __init__(self,*args,**kwargs):
1975 """
1987 """
1976 Map the system output streams to self.
1988 Map the system output streams to self.
1977 """
1989 """
1978 self.stream = StringIO.StringIO()
1990 self.stream = StringIO.StringIO()
1979 self.stdout = sys.stdout
1991 self.stdout = sys.stdout
1980 sys.stdout = self
1992 sys.stdout = self
1981 self.stderr = sys.stderr
1993 self.stderr = sys.stderr
1982 sys.stderr = self
1994 sys.stderr = self
1983
1995
1984 def write(self, text):
1996 def write(self, text):
1985 """
1997 """
1986 Write both to screen and to self.
1998 Write both to screen and to self.
1987 """
1999 """
1988 self.stream.write(text)
2000 self.stream.write(text)
1989 self.stdout.write(text)
2001 self.stdout.write(text)
1990 if "\n" in text:
2002 if "\n" in text:
1991 self.stdout.flush()
2003 self.stdout.flush()
1992
2004
1993 def writelines(self, lines):
2005 def writelines(self, lines):
1994 """
2006 """
1995 Write lines both to screen and to self.
2007 Write lines both to screen and to self.
1996 """
2008 """
1997 self.stream.writelines(lines)
2009 self.stream.writelines(lines)
1998 self.stdout.writelines(lines)
2010 self.stdout.writelines(lines)
1999 self.stdout.flush()
2011 self.stdout.flush()
2000
2012
2001 def restore(self):
2013 def restore(self):
2002 """
2014 """
2003 Restore the default system streams.
2015 Restore the default system streams.
2004 """
2016 """
2005 self.stdout.flush()
2017 self.stdout.flush()
2006 self.stderr.flush()
2018 self.stderr.flush()
2007 sys.stdout = self.stdout
2019 sys.stdout = self.stdout
2008 sys.stderr = self.stderr
2020 sys.stderr = self.stderr
2009
2021
2010
2022
2011 class icap(Table):
2023 class icap(Table):
2012 """
2024 """
2013 Execute a python string and capture any output to stderr/stdout.
2025 Execute a python string and capture any output to stderr/stdout.
2014
2026
2015 Examples:
2027 Examples::
2016
2028
2017 >>> import time
2029 >>> import time
2018 >>> icap("for i in range(10): print i, time.sleep(0.1)")
2030 >>> icap("for i in range(10): print i, time.sleep(0.1)")
2019
2031
2020 """
2032 """
2021 def __init__(self, expr, globals=None):
2033 def __init__(self, expr, globals=None):
2022 self.expr = expr
2034 self.expr = expr
2023 self.globals = globals
2035 self.globals = globals
2024 log = _RedirectIO()
2036 log = _RedirectIO()
2025 try:
2037 try:
2026 exec(expr, getglobals(globals))
2038 exec(expr, getglobals(globals))
2027 finally:
2039 finally:
2028 log.restore()
2040 log.restore()
2029 self.stream = log.stream
2041 self.stream = log.stream
2030
2042
2031 def __iter__(self):
2043 def __iter__(self):
2032 self.stream.seek(0)
2044 self.stream.seek(0)
2033 for line in self.stream:
2045 for line in self.stream:
2034 yield line.rstrip("\r\n")
2046 yield line.rstrip("\r\n")
2035
2047
2036 def __xrepr__(self, mode="default"):
2048 def __xrepr__(self, mode="default"):
2037 if mode == "header" or mode == "footer":
2049 if mode == "header" or mode == "footer":
2038 yield (astyle.style_default,
2050 yield (astyle.style_default,
2039 "%s(%r)" % (self.__class__.__name__, self.expr))
2051 "%s(%r)" % (self.__class__.__name__, self.expr))
2040 else:
2052 else:
2041 yield (astyle.style_default, repr(self))
2053 yield (astyle.style_default, repr(self))
2042
2054
2043 def __repr__(self):
2055 def __repr__(self):
2044 return "%s.%s(%r)" % \
2056 return "%s.%s(%r)" % \
2045 (self.__class__.__module__, self.__class__.__name__, self.expr)
2057 (self.__class__.__module__, self.__class__.__name__, self.expr)
2046
2058
2047
2059
2048 def xformat(value, mode, maxlength):
2060 def xformat(value, mode, maxlength):
2049 align = None
2061 align = None
2050 full = True
2062 full = True
2051 width = 0
2063 width = 0
2052 text = astyle.Text()
2064 text = astyle.Text()
2053 for (style, part) in xrepr(value, mode):
2065 for (style, part) in xrepr(value, mode):
2054 # only consider the first result
2066 # only consider the first result
2055 if align is None:
2067 if align is None:
2056 if isinstance(style, int):
2068 if isinstance(style, int):
2057 # (style, text) really is (alignment, stop)
2069 # (style, text) really is (alignment, stop)
2058 align = style
2070 align = style
2059 full = part
2071 full = part
2060 continue
2072 continue
2061 else:
2073 else:
2062 align = -1
2074 align = -1
2063 full = True
2075 full = True
2064 if not isinstance(style, int):
2076 if not isinstance(style, int):
2065 text.append((style, part))
2077 text.append((style, part))
2066 width += len(part)
2078 width += len(part)
2067 if width >= maxlength and not full:
2079 if width >= maxlength and not full:
2068 text.append((astyle.style_ellisis, "..."))
2080 text.append((astyle.style_ellisis, "..."))
2069 width += 3
2081 width += 3
2070 break
2082 break
2071 if align is None: # default to left alignment
2083 if align is None: # default to left alignment
2072 align = -1
2084 align = -1
2073 return (align, width, text)
2085 return (align, width, text)
2074
2086
2075
2087
2076
2088
2077 import astyle
2089 import astyle
2078
2090
2079 class idump(Display):
2091 class idump(Display):
2080 # The approximate maximum length of a column entry
2092 # The approximate maximum length of a column entry
2081 maxattrlength = 200
2093 maxattrlength = 200
2082
2094
2083 # Style for column names
2095 # Style for column names
2084 style_header = astyle.Style.fromstr("white:black:bold")
2096 style_header = astyle.Style.fromstr("white:black:bold")
2085
2097
2086 def __init__(self, input=None, *attrs):
2098 def __init__(self, input=None, *attrs):
2087 Display.__init__(self, input)
2099 Display.__init__(self, input)
2088 self.attrs = [upgradexattr(attr) for attr in attrs]
2100 self.attrs = [upgradexattr(attr) for attr in attrs]
2089 self.headerpadchar = " "
2101 self.headerpadchar = " "
2090 self.headersepchar = "|"
2102 self.headersepchar = "|"
2091 self.datapadchar = " "
2103 self.datapadchar = " "
2092 self.datasepchar = "|"
2104 self.datasepchar = "|"
2093
2105
2094 def display(self):
2106 def display(self):
2095 stream = genutils.Term.cout
2107 stream = genutils.Term.cout
2096 allattrs = []
2108 allattrs = []
2097 attrset = set()
2109 attrset = set()
2098 colwidths = {}
2110 colwidths = {}
2099 rows = []
2111 rows = []
2100 for item in xiter(self.input):
2112 for item in xiter(self.input):
2101 row = {}
2113 row = {}
2102 attrs = self.attrs
2114 attrs = self.attrs
2103 if not attrs:
2115 if not attrs:
2104 attrs = xattrs(item, "default")
2116 attrs = xattrs(item, "default")
2105 for attr in attrs:
2117 for attr in attrs:
2106 if attr not in attrset:
2118 if attr not in attrset:
2107 allattrs.append(attr)
2119 allattrs.append(attr)
2108 attrset.add(attr)
2120 attrset.add(attr)
2109 colwidths[attr] = len(attr.name())
2121 colwidths[attr] = len(attr.name())
2110 try:
2122 try:
2111 value = attr.value(item)
2123 value = attr.value(item)
2112 except (KeyboardInterrupt, SystemExit):
2124 except (KeyboardInterrupt, SystemExit):
2113 raise
2125 raise
2114 except Exception, exc:
2126 except Exception, exc:
2115 value = exc
2127 value = exc
2116 (align, width, text) = xformat(value, "cell", self.maxattrlength)
2128 (align, width, text) = xformat(value, "cell", self.maxattrlength)
2117 colwidths[attr] = max(colwidths[attr], width)
2129 colwidths[attr] = max(colwidths[attr], width)
2118 # remember alignment, length and colored parts
2130 # remember alignment, length and colored parts
2119 row[attr] = (align, width, text)
2131 row[attr] = (align, width, text)
2120 rows.append(row)
2132 rows.append(row)
2121
2133
2122 stream.write("\n")
2134 stream.write("\n")
2123 for (i, attr) in enumerate(allattrs):
2135 for (i, attr) in enumerate(allattrs):
2124 attrname = attr.name()
2136 attrname = attr.name()
2125 self.style_header(attrname).write(stream)
2137 self.style_header(attrname).write(stream)
2126 spc = colwidths[attr] - len(attrname)
2138 spc = colwidths[attr] - len(attrname)
2127 if i < len(colwidths)-1:
2139 if i < len(colwidths)-1:
2128 stream.write(self.headerpadchar*spc)
2140 stream.write(self.headerpadchar*spc)
2129 stream.write(self.headersepchar)
2141 stream.write(self.headersepchar)
2130 stream.write("\n")
2142 stream.write("\n")
2131
2143
2132 for row in rows:
2144 for row in rows:
2133 for (i, attr) in enumerate(allattrs):
2145 for (i, attr) in enumerate(allattrs):
2134 (align, width, text) = row[attr]
2146 (align, width, text) = row[attr]
2135 spc = colwidths[attr] - width
2147 spc = colwidths[attr] - width
2136 if align == -1:
2148 if align == -1:
2137 text.write(stream)
2149 text.write(stream)
2138 if i < len(colwidths)-1:
2150 if i < len(colwidths)-1:
2139 stream.write(self.datapadchar*spc)
2151 stream.write(self.datapadchar*spc)
2140 elif align == 0:
2152 elif align == 0:
2141 spc = colwidths[attr] - width
2153 spc = colwidths[attr] - width
2142 spc1 = spc//2
2154 spc1 = spc//2
2143 spc2 = spc-spc1
2155 spc2 = spc-spc1
2144 stream.write(self.datapadchar*spc1)
2156 stream.write(self.datapadchar*spc1)
2145 text.write(stream)
2157 text.write(stream)
2146 if i < len(colwidths)-1:
2158 if i < len(colwidths)-1:
2147 stream.write(self.datapadchar*spc2)
2159 stream.write(self.datapadchar*spc2)
2148 else:
2160 else:
2149 stream.write(self.datapadchar*spc)
2161 stream.write(self.datapadchar*spc)
2150 text.write(stream)
2162 text.write(stream)
2151 if i < len(colwidths)-1:
2163 if i < len(colwidths)-1:
2152 stream.write(self.datasepchar)
2164 stream.write(self.datasepchar)
2153 stream.write("\n")
2165 stream.write("\n")
2154
2166
2155
2167
2156 class AttributeDetail(Table):
2168 class AttributeDetail(Table):
2157 """
2169 """
2158 ``AttributeDetail`` objects are use for displaying a detailed list of object
2170 ``AttributeDetail`` objects are use for displaying a detailed list of object
2159 attributes.
2171 attributes.
2160 """
2172 """
2161 def __init__(self, object, descriptor):
2173 def __init__(self, object, descriptor):
2162 self.object = object
2174 self.object = object
2163 self.descriptor = descriptor
2175 self.descriptor = descriptor
2164
2176
2165 def __iter__(self):
2177 def __iter__(self):
2166 return self.descriptor.iter(self.object)
2178 return self.descriptor.iter(self.object)
2167
2179
2168 def name(self):
2180 def name(self):
2169 return self.descriptor.name()
2181 return self.descriptor.name()
2170
2182
2171 def attrtype(self):
2183 def attrtype(self):
2172 return self.descriptor.attrtype(self.object)
2184 return self.descriptor.attrtype(self.object)
2173
2185
2174 def valuetype(self):
2186 def valuetype(self):
2175 return self.descriptor.valuetype(self.object)
2187 return self.descriptor.valuetype(self.object)
2176
2188
2177 def doc(self):
2189 def doc(self):
2178 return self.descriptor.doc(self.object)
2190 return self.descriptor.doc(self.object)
2179
2191
2180 def shortdoc(self):
2192 def shortdoc(self):
2181 return self.descriptor.shortdoc(self.object)
2193 return self.descriptor.shortdoc(self.object)
2182
2194
2183 def value(self):
2195 def value(self):
2184 return self.descriptor.value(self.object)
2196 return self.descriptor.value(self.object)
2185
2197
2186 def __xattrs__(self, mode="default"):
2198 def __xattrs__(self, mode="default"):
2187 attrs = ("name()", "attrtype()", "valuetype()", "value()", "shortdoc()")
2199 attrs = ("name()", "attrtype()", "valuetype()", "value()", "shortdoc()")
2188 if mode == "detail":
2200 if mode == "detail":
2189 attrs += ("doc()",)
2201 attrs += ("doc()",)
2190 return attrs
2202 return attrs
2191
2203
2192 def __xrepr__(self, mode="default"):
2204 def __xrepr__(self, mode="default"):
2193 yield (-1, True)
2205 yield (-1, True)
2194 valuetype = self.valuetype()
2206 valuetype = self.valuetype()
2195 if valuetype is not noitem:
2207 if valuetype is not noitem:
2196 for part in xrepr(valuetype):
2208 for part in xrepr(valuetype):
2197 yield part
2209 yield part
2198 yield (astyle.style_default, " ")
2210 yield (astyle.style_default, " ")
2199 yield (astyle.style_default, self.attrtype())
2211 yield (astyle.style_default, self.attrtype())
2200 yield (astyle.style_default, " ")
2212 yield (astyle.style_default, " ")
2201 yield (astyle.style_default, self.name())
2213 yield (astyle.style_default, self.name())
2202 yield (astyle.style_default, " of ")
2214 yield (astyle.style_default, " of ")
2203 for part in xrepr(self.object):
2215 for part in xrepr(self.object):
2204 yield part
2216 yield part
2205
2217
2206
2218
2207 try:
2219 try:
2208 from ibrowse import ibrowse
2220 from ibrowse import ibrowse
2209 except ImportError:
2221 except ImportError:
2210 # No curses (probably Windows) => try igrid
2222 # No curses (probably Windows) => try igrid
2211 try:
2223 try:
2212 from igrid import igrid
2224 from igrid import igrid
2213 except ImportError:
2225 except ImportError:
2214 # no wx either => use ``idump`` as the default display.
2226 # no wx either => use ``idump`` as the default display.
2215 defaultdisplay = idump
2227 defaultdisplay = idump
2216 else:
2228 else:
2217 defaultdisplay = igrid
2229 defaultdisplay = igrid
2218 __all__.append("igrid")
2230 __all__.append("igrid")
2219 else:
2231 else:
2220 defaultdisplay = ibrowse
2232 defaultdisplay = ibrowse
2221 __all__.append("ibrowse")
2233 __all__.append("ibrowse")
2222
2234
2223
2235
2224 # If we're running under IPython, register our objects with IPython's
2236 # If we're running under IPython, register our objects with IPython's
2225 # generic function ``result_display``, else install a displayhook
2237 # generic function ``result_display``, else install a displayhook
2226 # directly as sys.displayhook
2238 # directly as sys.displayhook
2227 if generics is not None:
2239 if generics is not None:
2228 def display_display(obj):
2240 def display_display(obj):
2229 return obj.display()
2241 return obj.display()
2230 generics.result_display.when_type(Display)(display_display)
2242 generics.result_display.when_type(Display)(display_display)
2231
2243
2232 def display_tableobject(obj):
2244 def display_tableobject(obj):
2233 return display_display(defaultdisplay(obj))
2245 return display_display(defaultdisplay(obj))
2234 generics.result_display.when_type(Table)(display_tableobject)
2246 generics.result_display.when_type(Table)(display_tableobject)
2235
2247
2236 def display_tableclass(obj):
2248 def display_tableclass(obj):
2237 return display_tableobject(obj())
2249 return display_tableobject(obj())
2238 generics.result_display.when_type(Table.__metaclass__)(display_tableclass)
2250 generics.result_display.when_type(Table.__metaclass__)(display_tableclass)
2239 else:
2251 else:
2240 def installdisplayhook():
2252 def installdisplayhook():
2241 _originalhook = sys.displayhook
2253 _originalhook = sys.displayhook
2242 def displayhook(obj):
2254 def displayhook(obj):
2243 if isinstance(obj, type) and issubclass(obj, Table):
2255 if isinstance(obj, type) and issubclass(obj, Table):
2244 obj = obj()
2256 obj = obj()
2245 if isinstance(obj, Table):
2257 if isinstance(obj, Table):
2246 obj = defaultdisplay(obj)
2258 obj = defaultdisplay(obj)
2247 if isinstance(obj, Display):
2259 if isinstance(obj, Display):
2248 return obj.display()
2260 return obj.display()
2249 else:
2261 else:
2250 _originalhook(obj)
2262 _originalhook(obj)
2251 sys.displayhook = displayhook
2263 sys.displayhook = displayhook
2252 installdisplayhook()
2264 installdisplayhook()
General Comments 0
You need to be logged in to leave comments. Login now