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