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