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