##// END OF EJS Templates
Make left alignment and full output the default...
walter.doerwald -
Show More
@@ -1,1864 +1,1838 b''
1 # -*- coding: iso-8859-1 -*-
1 # -*- coding: iso-8859-1 -*-
2
2
3 """
3 """
4 ``ipipe`` provides classes to be used in an interactive Python session. Doing a
4 ``ipipe`` provides classes to be used in an interactive Python session. Doing a
5 ``from ipipe import *`` is the preferred way to do this. The name of all
5 ``from ipipe import *`` is the preferred way to do this. The name of all
6 objects imported this way starts with ``i`` to minimize collisions.
6 objects imported this way starts with ``i`` to minimize collisions.
7
7
8 ``ipipe`` supports "pipeline expressions", which is something resembling Unix
8 ``ipipe`` supports "pipeline expressions", which is something resembling Unix
9 pipes. An example is:
9 pipes. An example is:
10
10
11 >>> ienv | isort("key.lower()")
11 >>> ienv | isort("key.lower()")
12
12
13 This gives a listing of all environment variables sorted by name.
13 This gives a listing of all environment variables sorted by name.
14
14
15
15
16 There are three types of objects in a pipeline expression:
16 There are three types of objects in a pipeline expression:
17
17
18 * ``Table``s: These objects produce items. Examples are ``ls`` (listing the
18 * ``Table``s: These objects produce items. Examples are ``ls`` (listing the
19 current directory, ``ienv`` (listing environment variables), ``ipwd`` (listing
19 current directory, ``ienv`` (listing environment variables), ``ipwd`` (listing
20 user account) and ``igrp`` (listing user groups). A ``Table`` must be the
20 user account) 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 ``browse`` which is a ``curses``
32 display objects will be used. One example is ``browse`` 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)``. This method must return a
40 implement the method ``__xattrs__(self, mode)``. This method must return a
41 sequence of attribute names. This sequence may also contain integers, which
41 sequence of attribute names. This sequence may also contain integers, which
42 will be treated as sequence indizes. Also supported is ``None``, which uses
42 will be treated as sequence indizes. Also supported is ``None``, which uses
43 the object itself and callables which will be called with the object as the
43 the object itself and callables which will be called with the object as the
44 an argument. If ``__xattrs__()`` isn't implemented ``(None,)`` will be used as
44 an argument. If ``__xattrs__()`` isn't implemented ``(None,)`` will be used as
45 the attribute sequence (i.e. the object itself (it's ``repr()`` format) will
45 the attribute sequence (i.e. the object itself (it's ``repr()`` format) will
46 be being displayed. The global function ``xattrs()`` implements this
46 be being displayed. The global function ``xattrs()`` implements this
47 functionality.
47 functionality.
48
48
49 * When an object ``foo`` is displayed in the header, footer or table cell of the
49 * When an object ``foo`` is displayed in the header, footer or table cell of the
50 browser ``foo.__xrepr__(mode)`` is called. Mode can be ``"header"`` or
50 browser ``foo.__xrepr__(mode)`` is called. Mode can be ``"header"`` or
51 ``"footer"`` for the header or footer line and ``"cell"`` for a table cell.
51 ``"footer"`` for the header or footer line and ``"cell"`` for a table cell.
52 ``__xrepr__()```must return an iterable (e.g. by being a generator) which
52 ``__xrepr__()```must return an iterable (e.g. by being a generator) which
53 produces the following items: The first item should be a tuple containing
53 produces the following items: The first item should be a tuple containing
54 the alignment (-1 left aligned, 0 centered and 1 right aligned) and whether
54 the alignment (-1 left aligned, 0 centered and 1 right aligned) and whether
55 the complete output must be displayed or if the browser is allowed to stop
55 the complete output must be displayed or if the browser is allowed to stop
56 output after enough text has been produced (e.g. a syntax highlighted text
56 output after enough text has been produced (e.g. a syntax highlighted text
57 line would use ``True``, but for a large data structure (i.e. a nested list,
57 line would use ``True``, but for a large data structure (i.e. a nested list,
58 tuple or dictionary) ``False`` would be used). The other output ``__xrepr__()``
58 tuple or dictionary) ``False`` would be used). The other output ``__xrepr__()``
59 may produce is tuples of ``Style```objects and text (which contain the text
59 may produce is tuples of ``Style```objects and text (which contain the text
60 representation of the object; see the ``astyle`` module). If ``__xrepr__()``
60 representation of the object; see the ``astyle`` module). If ``__xrepr__()``
61 recursively outputs a data structure the function ``xrepr(object, mode)`` can
61 recursively outputs a data structure the function ``xrepr(object, mode)`` can
62 be used and ``"default"`` must be passed as the mode in these calls. This in
62 be used and ``"default"`` must be passed as the mode in these calls. This in
63 turn calls the ``__xrepr__()`` method on ``object`` (or uses ``repr(object)``
63 turn calls the ``__xrepr__()`` method on ``object`` (or uses ``repr(object)``
64 as the string representation if ``__xrepr__()`` doesn't exist).
64 as the string representation if ``__xrepr__()`` doesn't exist).
65
65
66 * Objects that can be iterated by ``Pipe``s must implement the method
66 * Objects that can be iterated by ``Pipe``s must implement the method
67 ``__xiter__(self, mode)``. ``mode`` can take the following values:
67 ``__xiter__(self, mode)``. ``mode`` can take the following values:
68
68
69 - ``"default"``: This is the default value and ist always used by pipeline
69 - ``"default"``: This is the default value and ist always used by pipeline
70 expressions. Other values are only used in the browser.
70 expressions. Other values are only used in the browser.
71 - ``None``: This value is passed by the browser. The object must return an
71 - ``None``: This value is passed by the browser. The object must return an
72 iterable of ``XMode`` objects describing all modes supported by the object.
72 iterable of ``XMode`` objects describing all modes supported by the object.
73 (This should never include ``"default"`` or ``None``).
73 (This should never include ``"default"`` or ``None``).
74 - Any other value that the object supports.
74 - Any other value that the object supports.
75
75
76 The global function ``xiter()`` can be called to get such an iterator. If
76 The global function ``xiter()`` can be called to get such an iterator. If
77 the method ``_xiter__`` isn't implemented, ``xiter()`` falls back to
77 the method ``_xiter__`` isn't implemented, ``xiter()`` falls back to
78 ``__iter__``. In addition to that, dictionaries and modules receive special
78 ``__iter__``. In addition to that, dictionaries and modules receive special
79 treatment (returning an iterator over ``(key, value)`` pairs). This makes it
79 treatment (returning an iterator over ``(key, value)`` pairs). This makes it
80 possible to use dictionaries and modules in pipeline expressions, for example:
80 possible to use dictionaries and modules in pipeline expressions, for example:
81
81
82 >>> import sys
82 >>> import sys
83 >>> sys | ifilter("isinstance(value, int)") | idump
83 >>> sys | ifilter("isinstance(value, int)") | idump
84 key |value
84 key |value
85 api_version| 1012
85 api_version| 1012
86 dllhandle | 503316480
86 dllhandle | 503316480
87 hexversion | 33817328
87 hexversion | 33817328
88 maxint |2147483647
88 maxint |2147483647
89 maxunicode | 65535
89 maxunicode | 65535
90 >>> sys.modules | ifilter("_.value is not None") | isort("_.key.lower()")
90 >>> sys.modules | ifilter("_.value is not None") | isort("_.key.lower()")
91 ...
91 ...
92
92
93 Note: The expression strings passed to ``ifilter()`` and ``isort()`` can
93 Note: The expression strings passed to ``ifilter()`` and ``isort()`` can
94 refer to the object to be filtered or sorted via the variable ``_`` and to any
94 refer to the object to be filtered or sorted via the variable ``_`` and to any
95 of the attributes of the object, i.e.:
95 of the attributes of the object, i.e.:
96
96
97 >>> sys.modules | ifilter("_.value is not None") | isort("_.key.lower()")
97 >>> sys.modules | ifilter("_.value is not None") | isort("_.key.lower()")
98
98
99 does the same as
99 does the same as
100
100
101 >>> sys.modules | ifilter("value is not None") | isort("key.lower()")
101 >>> sys.modules | ifilter("value is not None") | isort("key.lower()")
102
102
103 In addition to expression strings, it's possible to pass callables (taking
103 In addition to expression strings, it's possible to pass callables (taking
104 the object as an argument) to ``ifilter()``, ``isort()`` and ``ieval()``:
104 the object as an argument) to ``ifilter()``, ``isort()`` and ``ieval()``:
105
105
106 >>> sys | ifilter(lambda _:isinstance(_.value, int)) \
106 >>> sys | ifilter(lambda _:isinstance(_.value, int)) \
107 ... | ieval(lambda _: (_.key, hex(_.value))) | idump
107 ... | ieval(lambda _: (_.key, hex(_.value))) | idump
108 0 |1
108 0 |1
109 api_version|0x3f4
109 api_version|0x3f4
110 dllhandle |0x1e000000
110 dllhandle |0x1e000000
111 hexversion |0x20402f0
111 hexversion |0x20402f0
112 maxint |0x7fffffff
112 maxint |0x7fffffff
113 maxunicode |0xffff
113 maxunicode |0xffff
114 """
114 """
115
115
116 import sys, os, os.path, stat, glob, new, csv, datetime, types
116 import sys, os, os.path, stat, glob, new, csv, datetime, types
117 import itertools, mimetypes
117 import itertools, mimetypes
118
118
119 try: # Python 2.3 compatibility
119 try: # Python 2.3 compatibility
120 import collections
120 import collections
121 except ImportError:
121 except ImportError:
122 deque = list
122 deque = list
123 else:
123 else:
124 deque = collections.deque
124 deque = collections.deque
125
125
126 try: # Python 2.3 compatibility
126 try: # Python 2.3 compatibility
127 set
127 set
128 except NameError:
128 except NameError:
129 import sets
129 import sets
130 set = sets.Set
130 set = sets.Set
131
131
132 try: # Python 2.3 compatibility
132 try: # Python 2.3 compatibility
133 sorted
133 sorted
134 except NameError:
134 except NameError:
135 def sorted(iterator, key=None, reverse=False):
135 def sorted(iterator, key=None, reverse=False):
136 items = list(iterator)
136 items = list(iterator)
137 if key is not None:
137 if key is not None:
138 items.sort(lambda i1, i2: cmp(key(i1), key(i2)))
138 items.sort(lambda i1, i2: cmp(key(i1), key(i2)))
139 else:
139 else:
140 items.sort()
140 items.sort()
141 if reverse:
141 if reverse:
142 items.reverse()
142 items.reverse()
143 return items
143 return items
144
144
145 try:
145 try:
146 import pwd
146 import pwd
147 except ImportError:
147 except ImportError:
148 pwd = None
148 pwd = None
149
149
150 try:
150 try:
151 import grp
151 import grp
152 except ImportError:
152 except ImportError:
153 grp = None
153 grp = None
154
154
155 import path
155 import path
156 try:
156 try:
157 from IPython import genutils, ipapi
157 from IPython import genutils, ipapi
158 except ImportError:
158 except ImportError:
159 genutils = None
159 genutils = None
160 ipapi = None
160 ipapi = None
161
161
162 import astyle
162 import astyle
163
163
164
164
165 __all__ = [
165 __all__ = [
166 "ifile", "ils", "iglob", "iwalk", "ipwdentry", "ipwd", "igrpentry", "igrp",
166 "ifile", "ils", "iglob", "iwalk", "ipwdentry", "ipwd", "igrpentry", "igrp",
167 "icsv", "ix", "ichain", "isort", "ifilter", "ieval", "ienum", "ienv",
167 "icsv", "ix", "ichain", "isort", "ifilter", "ieval", "ienum", "ienv",
168 "idump", "iless"
168 "idump", "iless"
169 ]
169 ]
170
170
171
171
172 os.stat_float_times(True) # enable microseconds
172 os.stat_float_times(True) # enable microseconds
173
173
174
174
175 class AttrNamespace(object):
175 class AttrNamespace(object):
176 """
176 """
177 Helper class that is used for providing a namespace for evaluating
177 Helper class that is used for providing a namespace for evaluating
178 expressions containing attribute names of an object.
178 expressions containing attribute names of an object.
179 """
179 """
180 def __init__(self, wrapped):
180 def __init__(self, wrapped):
181 self.wrapped = wrapped
181 self.wrapped = wrapped
182
182
183 def __getitem__(self, name):
183 def __getitem__(self, name):
184 if name == "_":
184 if name == "_":
185 return self.wrapped
185 return self.wrapped
186 try:
186 try:
187 return getattr(self.wrapped, name)
187 return getattr(self.wrapped, name)
188 except AttributeError:
188 except AttributeError:
189 raise KeyError(name)
189 raise KeyError(name)
190
190
191 # Python 2.3 compatibility
191 # Python 2.3 compatibility
192 # use eval workaround to find out which names are used in the
192 # use eval workaround to find out which names are used in the
193 # eval string and put them into the locals. This works for most
193 # eval string and put them into the locals. This works for most
194 # normal uses case, bizarre ones like accessing the locals()
194 # normal uses case, bizarre ones like accessing the locals()
195 # will fail
195 # will fail
196 try:
196 try:
197 eval("_", None, AttrNamespace(None))
197 eval("_", None, AttrNamespace(None))
198 except TypeError:
198 except TypeError:
199 real_eval = eval
199 real_eval = eval
200 def eval(codestring, _globals, _locals):
200 def eval(codestring, _globals, _locals):
201 """
201 """
202 eval(source[, globals[, locals]]) -> value
202 eval(source[, globals[, locals]]) -> value
203
203
204 Evaluate the source in the context of globals and locals.
204 Evaluate the source in the context of globals and locals.
205 The source may be a string representing a Python expression
205 The source may be a string representing a Python expression
206 or a code object as returned by compile().
206 or a code object as returned by compile().
207 The globals must be a dictionary and locals can be any mappping.
207 The globals must be a dictionary and locals can be any mappping.
208
208
209 This function is a workaround for the shortcomings of
209 This function is a workaround for the shortcomings of
210 Python 2.3's eval.
210 Python 2.3's eval.
211 """
211 """
212
212
213 code = compile(codestring, "_eval", "eval")
213 code = compile(codestring, "_eval", "eval")
214 newlocals = {}
214 newlocals = {}
215 for name in code.co_names:
215 for name in code.co_names:
216 try:
216 try:
217 newlocals[name] = _locals[name]
217 newlocals[name] = _locals[name]
218 except KeyError:
218 except KeyError:
219 pass
219 pass
220 return real_eval(code, _globals, newlocals)
220 return real_eval(code, _globals, newlocals)
221
221
222
222
223 noitem = object()
223 noitem = object()
224
224
225 def item(iterator, index, default=noitem):
225 def item(iterator, index, default=noitem):
226 """
226 """
227 Return the ``index``th item from the iterator ``iterator``.
227 Return the ``index``th item from the iterator ``iterator``.
228 ``index`` must be an integer (negative integers are relative to the
228 ``index`` must be an integer (negative integers are relative to the
229 end (i.e. the last item produced by the iterator)).
229 end (i.e. the last item produced by the iterator)).
230
230
231 If ``default`` is given, this will be the default value when
231 If ``default`` is given, this will be the default value when
232 the iterator doesn't contain an item at this position. Otherwise an
232 the iterator doesn't contain an item at this position. Otherwise an
233 ``IndexError`` will be raised.
233 ``IndexError`` will be raised.
234
234
235 Note that using this function will partially or totally exhaust the
235 Note that using this function will partially or totally exhaust the
236 iterator.
236 iterator.
237 """
237 """
238 i = index
238 i = index
239 if i>=0:
239 if i>=0:
240 for item in iterator:
240 for item in iterator:
241 if not i:
241 if not i:
242 return item
242 return item
243 i -= 1
243 i -= 1
244 else:
244 else:
245 i = -index
245 i = -index
246 cache = deque()
246 cache = deque()
247 for item in iterator:
247 for item in iterator:
248 cache.append(item)
248 cache.append(item)
249 if len(cache)>i:
249 if len(cache)>i:
250 cache.popleft()
250 cache.popleft()
251 if len(cache)==i:
251 if len(cache)==i:
252 return cache.popleft()
252 return cache.popleft()
253 if default is noitem:
253 if default is noitem:
254 raise IndexError(index)
254 raise IndexError(index)
255 else:
255 else:
256 return default
256 return default
257
257
258
258
259 def getglobals(g):
259 def getglobals(g):
260 if g is None:
260 if g is None:
261 if ipapi is not None:
261 if ipapi is not None:
262 return ipapi.get().user_ns()
262 return ipapi.get().user_ns()
263 else:
263 else:
264 return globals()
264 return globals()
265 return g
265 return g
266
266
267
267
268 class Table(object):
268 class Table(object):
269 """
269 """
270 A ``Table`` is an object that produces items (just like a normal Python
270 A ``Table`` is an object that produces items (just like a normal Python
271 iterator/generator does) and can be used as the first object in a pipeline
271 iterator/generator does) and can be used as the first object in a pipeline
272 expression. The displayhook will open the default browser for such an object
272 expression. The displayhook will open the default browser for such an object
273 (instead of simply printing the ``repr()`` result).
273 (instead of simply printing the ``repr()`` result).
274 """
274 """
275
275
276 # We want to support ``foo`` and ``foo()`` in pipeline expression:
276 # We want to support ``foo`` and ``foo()`` in pipeline expression:
277 # So we implement the required operators (``|`` and ``+``) in the metaclass,
277 # So we implement the required operators (``|`` and ``+``) in the metaclass,
278 # instantiate the class and forward the operator to the instance
278 # instantiate the class and forward the operator to the instance
279 class __metaclass__(type):
279 class __metaclass__(type):
280 def __iter__(self):
280 def __iter__(self):
281 return iter(self())
281 return iter(self())
282
282
283 def __or__(self, other):
283 def __or__(self, other):
284 return self() | other
284 return self() | other
285
285
286 def __add__(self, other):
286 def __add__(self, other):
287 return self() + other
287 return self() + other
288
288
289 def __radd__(self, other):
289 def __radd__(self, other):
290 return other + self()
290 return other + self()
291
291
292 def __getitem__(self, index):
292 def __getitem__(self, index):
293 return self()[index]
293 return self()[index]
294
294
295 def __getitem__(self, index):
295 def __getitem__(self, index):
296 return item(self, index)
296 return item(self, index)
297
297
298 def __contains__(self, item):
298 def __contains__(self, item):
299 for haveitem in self:
299 for haveitem in self:
300 if item == haveitem:
300 if item == haveitem:
301 return True
301 return True
302 return False
302 return False
303
303
304 def __or__(self, other):
304 def __or__(self, other):
305 # autoinstantiate right hand side
305 # autoinstantiate right hand side
306 if isinstance(other, type) and issubclass(other, (Table, Display)):
306 if isinstance(other, type) and issubclass(other, (Table, Display)):
307 other = other()
307 other = other()
308 # treat simple strings and functions as ``ieval`` instances
308 # treat simple strings and functions as ``ieval`` instances
309 elif not isinstance(other, Display) and not isinstance(other, Table):
309 elif not isinstance(other, Display) and not isinstance(other, Table):
310 other = ieval(other)
310 other = ieval(other)
311 # forward operations to the right hand side
311 # forward operations to the right hand side
312 return other.__ror__(self)
312 return other.__ror__(self)
313
313
314 def __add__(self, other):
314 def __add__(self, other):
315 # autoinstantiate right hand side
315 # autoinstantiate right hand side
316 if isinstance(other, type) and issubclass(other, Table):
316 if isinstance(other, type) and issubclass(other, Table):
317 other = other()
317 other = other()
318 return ichain(self, other)
318 return ichain(self, other)
319
319
320 def __radd__(self, other):
320 def __radd__(self, other):
321 # autoinstantiate left hand side
321 # autoinstantiate left hand side
322 if isinstance(other, type) and issubclass(other, Table):
322 if isinstance(other, type) and issubclass(other, Table):
323 other = other()
323 other = other()
324 return ichain(other, self)
324 return ichain(other, self)
325
325
326 def __iter__(self):
326 def __iter__(self):
327 return xiter(self, "default")
327 return xiter(self, "default")
328
328
329
329
330 class Pipe(Table):
330 class Pipe(Table):
331 """
331 """
332 A ``Pipe`` is an object that can be used in a pipeline expression. It
332 A ``Pipe`` is an object that can be used in a pipeline expression. It
333 processes the objects it gets from its input ``Table``/``Pipe``. Note that
333 processes the objects it gets from its input ``Table``/``Pipe``. Note that
334 a ``Pipe`` object can't be used as the first object in a pipeline
334 a ``Pipe`` object can't be used as the first object in a pipeline
335 expression, as it doesn't produces items itself.
335 expression, as it doesn't produces items itself.
336 """
336 """
337 class __metaclass__(Table.__metaclass__):
337 class __metaclass__(Table.__metaclass__):
338 def __ror__(self, input):
338 def __ror__(self, input):
339 return input | self()
339 return input | self()
340
340
341 def __ror__(self, input):
341 def __ror__(self, input):
342 # autoinstantiate left hand side
342 # autoinstantiate left hand side
343 if isinstance(input, type) and issubclass(input, Table):
343 if isinstance(input, type) and issubclass(input, Table):
344 input = input()
344 input = input()
345 self.input = input
345 self.input = input
346 return self
346 return self
347
347
348
348
349 def _getattr(obj, name, default=noitem):
349 def _getattr(obj, name, default=noitem):
350 """
350 """
351 Internal helper for getting an attribute of an item. If ``name`` is ``None``
351 Internal helper for getting an attribute of an item. If ``name`` is ``None``
352 return the object itself. If ``name`` is an integer, use ``__getitem__``
352 return the object itself. If ``name`` is an integer, use ``__getitem__``
353 instead. If the attribute or item does not exist, return ``default``.
353 instead. If the attribute or item does not exist, return ``default``.
354 """
354 """
355 if name is None:
355 if name is None:
356 return obj
356 return obj
357 elif isinstance(name, basestring):
357 elif isinstance(name, basestring):
358 if name.endswith("()"):
358 if name.endswith("()"):
359 return getattr(obj, name[:-2], default)()
359 return getattr(obj, name[:-2], default)()
360 else:
360 else:
361 return getattr(obj, name, default)
361 return getattr(obj, name, default)
362 elif callable(name):
362 elif callable(name):
363 try:
363 try:
364 return name(obj)
364 return name(obj)
365 except AttributeError:
365 except AttributeError:
366 return default
366 return default
367 else:
367 else:
368 try:
368 try:
369 return obj[name]
369 return obj[name]
370 except IndexError:
370 except IndexError:
371 return default
371 return default
372
372
373
373
374 def _attrname(name):
374 def _attrname(name):
375 """
375 """
376 Internal helper that gives a proper name for the attribute ``name``
376 Internal helper that gives a proper name for the attribute ``name``
377 (which might be ``None`` or an ``int``).
377 (which might be ``None`` or an ``int``).
378 """
378 """
379 if name is None:
379 if name is None:
380 return "_"
380 return "_"
381 elif isinstance(name, basestring):
381 elif isinstance(name, basestring):
382 return name
382 return name
383 elif callable(name):
383 elif callable(name):
384 return getattr(name, "__xname__", name.__name__)
384 return getattr(name, "__xname__", name.__name__)
385 else:
385 else:
386 return str(name)
386 return str(name)
387
387
388
388
389 def xrepr(item, mode):
389 def xrepr(item, mode):
390 try:
390 try:
391 func = item.__xrepr__
391 func = item.__xrepr__
392 except AttributeError:
392 except AttributeError:
393 pass
393 pass
394 else:
394 else:
395 try:
395 try:
396 for x in func(mode):
396 for x in func(mode):
397 yield x
397 yield x
398 except (KeyboardInterrupt, SystemExit):
398 except (KeyboardInterrupt, SystemExit):
399 raise
399 raise
400 except Exception:
400 except Exception:
401 yield (-1, True)
402 yield (astyle.style_default, repr(item))
401 yield (astyle.style_default, repr(item))
403 return
402 return
404 if item is None:
403 if item is None:
405 yield (-1, True)
406 yield (astyle.style_type_none, repr(item))
404 yield (astyle.style_type_none, repr(item))
407 elif isinstance(item, bool):
405 elif isinstance(item, bool):
408 yield (-1, True)
409 yield (astyle.style_type_bool, repr(item))
406 yield (astyle.style_type_bool, repr(item))
410 elif isinstance(item, str):
407 elif isinstance(item, str):
411 yield (-1, True)
412 if mode == "cell":
408 if mode == "cell":
413 yield (astyle.style_default, repr(item.expandtabs(tab))[1:-1])
409 yield (astyle.style_default, repr(item.expandtabs(tab))[1:-1])
414 else:
410 else:
415 yield (astyle.style_default, repr(item))
411 yield (astyle.style_default, repr(item))
416 elif isinstance(item, unicode):
412 elif isinstance(item, unicode):
417 yield (-1, True)
418 if mode == "cell":
413 if mode == "cell":
419 yield (astyle.style_default, repr(item.expandtabs(tab))[2:-1])
414 yield (astyle.style_default, repr(item.expandtabs(tab))[2:-1])
420 else:
415 else:
421 yield (astyle.style_default, repr(item))
416 yield (astyle.style_default, repr(item))
422 elif isinstance(item, (int, long, float)):
417 elif isinstance(item, (int, long, float)):
423 yield (1, True)
418 yield (1, True)
424 yield (astyle.style_type_number, repr(item))
419 yield (astyle.style_type_number, repr(item))
425 elif isinstance(item, complex):
420 elif isinstance(item, complex):
426 yield (-1, True)
427 yield (astyle.style_type_number, repr(item))
421 yield (astyle.style_type_number, repr(item))
428 elif isinstance(item, datetime.datetime):
422 elif isinstance(item, datetime.datetime):
429 yield (-1, True)
430 if mode == "cell":
423 if mode == "cell":
431 # Don't use strftime() here, as this requires year >= 1900
424 # Don't use strftime() here, as this requires year >= 1900
432 yield (astyle.style_type_datetime,
425 yield (astyle.style_type_datetime,
433 "%04d-%02d-%02d %02d:%02d:%02d.%06d" % \
426 "%04d-%02d-%02d %02d:%02d:%02d.%06d" % \
434 (item.year, item.month, item.day,
427 (item.year, item.month, item.day,
435 item.hour, item.minute, item.second,
428 item.hour, item.minute, item.second,
436 item.microsecond),
429 item.microsecond),
437 )
430 )
438 else:
431 else:
439 yield (astyle.style_type_datetime, repr(item))
432 yield (astyle.style_type_datetime, repr(item))
440 elif isinstance(item, datetime.date):
433 elif isinstance(item, datetime.date):
441 yield (-1, True)
442 if mode == "cell":
434 if mode == "cell":
443 yield (astyle.style_type_datetime,
435 yield (astyle.style_type_datetime,
444 "%04d-%02d-%02d" % (item.year, item.month, item.day))
436 "%04d-%02d-%02d" % (item.year, item.month, item.day))
445 else:
437 else:
446 yield (astyle.style_type_datetime, repr(item))
438 yield (astyle.style_type_datetime, repr(item))
447 elif isinstance(item, datetime.time):
439 elif isinstance(item, datetime.time):
448 yield (-1, True)
449 if mode == "cell":
440 if mode == "cell":
450 yield (astyle.style_type_datetime,
441 yield (astyle.style_type_datetime,
451 "%02d:%02d:%02d.%06d" % \
442 "%02d:%02d:%02d.%06d" % \
452 (item.hour, item.minute, item.second, item.microsecond))
443 (item.hour, item.minute, item.second, item.microsecond))
453 else:
444 else:
454 yield (astyle.style_type_datetime, repr(item))
445 yield (astyle.style_type_datetime, repr(item))
455 elif isinstance(item, datetime.timedelta):
446 elif isinstance(item, datetime.timedelta):
456 yield (-1, True)
457 yield (astyle.style_type_datetime, repr(item))
447 yield (astyle.style_type_datetime, repr(item))
458 elif isinstance(item, Exception):
448 elif isinstance(item, Exception):
459 yield (-1, True)
460 if item.__class__.__module__ == "exceptions":
449 if item.__class__.__module__ == "exceptions":
461 classname = item.__class__.__name__
450 classname = item.__class__.__name__
462 else:
451 else:
463 classname = "%s.%s" % \
452 classname = "%s.%s" % \
464 (item.__class__.__module__, item.__class__.__name__)
453 (item.__class__.__module__, item.__class__.__name__)
465 if mode == "header" or mode == "footer":
454 if mode == "header" or mode == "footer":
466 yield (astyle.style_error, "%s: %s" % (classname, item))
455 yield (astyle.style_error, "%s: %s" % (classname, item))
467 else:
456 else:
468 yield (astyle.style_error, classname)
457 yield (astyle.style_error, classname)
469 elif isinstance(item, (list, tuple)):
458 elif isinstance(item, (list, tuple)):
470 yield (-1, False)
471 if mode == "header" or mode == "footer":
459 if mode == "header" or mode == "footer":
472 if item.__class__.__module__ == "__builtin__":
460 if item.__class__.__module__ == "__builtin__":
473 classname = item.__class__.__name__
461 classname = item.__class__.__name__
474 else:
462 else:
475 classname = "%s.%s" % \
463 classname = "%s.%s" % \
476 (item.__class__.__module__,item.__class__.__name__)
464 (item.__class__.__module__,item.__class__.__name__)
477 yield (astyle.style_default,
465 yield (astyle.style_default,
478 "<%s object with %d items at 0x%x>" % \
466 "<%s object with %d items at 0x%x>" % \
479 (classname, len(item), id(item)))
467 (classname, len(item), id(item)))
480 else:
468 else:
469 yield (-1, False)
481 if isinstance(item, list):
470 if isinstance(item, list):
482 yield (astyle.style_default, "[")
471 yield (astyle.style_default, "[")
483 end = "]"
472 end = "]"
484 else:
473 else:
485 yield (astyle.style_default, "(")
474 yield (astyle.style_default, "(")
486 end = ")"
475 end = ")"
487 for (i, subitem) in enumerate(item):
476 for (i, subitem) in enumerate(item):
488 if i:
477 if i:
489 yield (astyle.style_default, ", ")
478 yield (astyle.style_default, ", ")
490 for part in xrepr(subitem, "default"):
479 for part in xrepr(subitem, "default"):
491 yield part
480 yield part
492 yield (astyle.style_default, end)
481 yield (astyle.style_default, end)
493 elif isinstance(item, (dict, types.DictProxyType)):
482 elif isinstance(item, (dict, types.DictProxyType)):
494 yield (-1, False)
495 if mode == "header" or mode == "footer":
483 if mode == "header" or mode == "footer":
496 if item.__class__.__module__ == "__builtin__":
484 if item.__class__.__module__ == "__builtin__":
497 classname = item.__class__.__name__
485 classname = item.__class__.__name__
498 else:
486 else:
499 classname = "%s.%s" % \
487 classname = "%s.%s" % \
500 (item.__class__.__module__,item.__class__.__name__)
488 (item.__class__.__module__,item.__class__.__name__)
501 yield (astyle.style_default,
489 yield (astyle.style_default,
502 "<%s object with %d items at 0x%x>" % \
490 "<%s object with %d items at 0x%x>" % \
503 (classname, len(item), id(item)))
491 (classname, len(item), id(item)))
504 else:
492 else:
493 yield (-1, False)
505 if isinstance(item, dict):
494 if isinstance(item, dict):
506 yield (astyle.style_default, "{")
495 yield (astyle.style_default, "{")
507 end = "}"
496 end = "}"
508 else:
497 else:
509 yield (astyle.style_default, "dictproxy((")
498 yield (astyle.style_default, "dictproxy((")
510 end = "})"
499 end = "})"
511 for (i, (key, value)) in enumerate(item.iteritems()):
500 for (i, (key, value)) in enumerate(item.iteritems()):
512 if i:
501 if i:
513 yield (astyle.style_default, ", ")
502 yield (astyle.style_default, ", ")
514 for part in xrepr(key, "default"):
503 for part in xrepr(key, "default"):
515 yield part
504 yield part
516 yield (astyle.style_default, ": ")
505 yield (astyle.style_default, ": ")
517 for part in xrepr(value, "default"):
506 for part in xrepr(value, "default"):
518 yield part
507 yield part
519 yield (astyle.style_default, end)
508 yield (astyle.style_default, end)
520 else:
509 else:
521 yield (-1, True)
522 yield (astyle.style_default, repr(item))
510 yield (astyle.style_default, repr(item))
523
511
524
512
525 def xattrs(item, mode):
513 def xattrs(item, mode):
526 try:
514 try:
527 func = item.__xattrs__
515 func = item.__xattrs__
528 except AttributeError:
516 except AttributeError:
529 if mode == "detail":
517 if mode == "detail":
530 return dir(item)
518 return dir(item)
531 else:
519 else:
532 return (None,)
520 return (None,)
533 else:
521 else:
534 try:
522 try:
535 return func(mode)
523 return func(mode)
536 except (KeyboardInterrupt, SystemExit):
524 except (KeyboardInterrupt, SystemExit):
537 raise
525 raise
538 except Exception:
526 except Exception:
539 return (None,)
527 return (None,)
540
528
541
529
542 def xiter(item, mode):
530 def xiter(item, mode):
543 if mode == "detail":
531 if mode == "detail":
544 def items():
532 def items():
545 for name in xattrs(item, mode):
533 for name in xattrs(item, mode):
546 yield XAttr(item, name)
534 yield XAttr(item, name)
547 return items()
535 return items()
548 try:
536 try:
549 func = item.__xiter__
537 func = item.__xiter__
550 except AttributeError:
538 except AttributeError:
551 if isinstance(item, (dict, types.DictProxyType)):
539 if isinstance(item, (dict, types.DictProxyType)):
552 def items(item):
540 def items(item):
553 fields = ("key", "value")
541 fields = ("key", "value")
554 for (key, value) in item.iteritems():
542 for (key, value) in item.iteritems():
555 yield Fields(fields, key=key, value=value)
543 yield Fields(fields, key=key, value=value)
556 return items(item)
544 return items(item)
557 elif isinstance(item, new.module):
545 elif isinstance(item, new.module):
558 def items(item):
546 def items(item):
559 fields = ("key", "value")
547 fields = ("key", "value")
560 for key in sorted(item.__dict__):
548 for key in sorted(item.__dict__):
561 yield Fields(fields, key=key, value=getattr(item, key))
549 yield Fields(fields, key=key, value=getattr(item, key))
562 return items(item)
550 return items(item)
563 elif isinstance(item, basestring):
551 elif isinstance(item, basestring):
564 if not len(item):
552 if not len(item):
565 raise ValueError("can't enter empty string")
553 raise ValueError("can't enter empty string")
566 lines = item.splitlines()
554 lines = item.splitlines()
567 if len(lines) <= 1:
555 if len(lines) <= 1:
568 raise ValueError("can't enter one line string")
556 raise ValueError("can't enter one line string")
569 return iter(lines)
557 return iter(lines)
570 return iter(item)
558 return iter(item)
571 else:
559 else:
572 return iter(func(mode)) # iter() just to be safe
560 return iter(func(mode)) # iter() just to be safe
573
561
574
562
575 class ichain(Pipe):
563 class ichain(Pipe):
576 """
564 """
577 Chains multiple ``Table``s into one.
565 Chains multiple ``Table``s into one.
578 """
566 """
579
567
580 def __init__(self, *iters):
568 def __init__(self, *iters):
581 self.iters = iters
569 self.iters = iters
582
570
583 def __xiter__(self, mode):
571 def __xiter__(self, mode):
584 return itertools.chain(*self.iters)
572 return itertools.chain(*self.iters)
585
573
586 def __xrepr__(self, mode):
574 def __xrepr__(self, mode):
587 yield (-1, True)
588 if mode == "header" or mode == "footer":
575 if mode == "header" or mode == "footer":
589 for (i, item) in enumerate(self.iters):
576 for (i, item) in enumerate(self.iters):
590 if i:
577 if i:
591 yield (astyle.style_default, "+")
578 yield (astyle.style_default, "+")
592 if isinstance(item, Pipe):
579 if isinstance(item, Pipe):
593 yield (astyle.style_default, "(")
580 yield (astyle.style_default, "(")
594 for part in xrepr(item, mode):
581 for part in xrepr(item, mode):
595 yield part
582 yield part
596 if isinstance(item, Pipe):
583 if isinstance(item, Pipe):
597 yield (astyle.style_default, ")")
584 yield (astyle.style_default, ")")
598 else:
585 else:
599 yield (astyle.style_default, repr(self))
586 yield (astyle.style_default, repr(self))
600
587
601 def __repr__(self):
588 def __repr__(self):
602 args = ", ".join([repr(it) for it in self.iters])
589 args = ", ".join([repr(it) for it in self.iters])
603 return "%s.%s(%s)" % \
590 return "%s.%s(%s)" % \
604 (self.__class__.__module__, self.__class__.__name__, args)
591 (self.__class__.__module__, self.__class__.__name__, args)
605
592
606
593
607 class ifile(path.path):
594 class ifile(path.path):
608 """
595 """
609 file (or directory) object.
596 file (or directory) object.
610 """
597 """
611
598
612 def __add_(self, other):
599 def __add_(self, other):
613 return ifile(path._base(self) + other)
600 return ifile(path._base(self) + other)
614
601
615 def __radd_(self, other):
602 def __radd_(self, other):
616 return ifile(other + path._base(self))
603 return ifile(other + path._base(self))
617
604
618 def __div_(self, other):
605 def __div_(self, other):
619 return ifile(path.__div__(self, other))
606 return ifile(path.__div__(self, other))
620
607
621 def getcwd():
608 def getcwd():
622 return ifile(path.path.getcwd())
609 return ifile(path.path.getcwd())
623 getcwd.__doc__ = path.path.getcwd.__doc__
610 getcwd.__doc__ = path.path.getcwd.__doc__
624 getcwd = staticmethod(getcwd)
611 getcwd = staticmethod(getcwd)
625
612
626 def abspath(self):
613 def abspath(self):
627 return ifile(path.path.abspath(self))
614 return ifile(path.path.abspath(self))
628 abspath.__doc__ = path.path.abspath.__doc__
615 abspath.__doc__ = path.path.abspath.__doc__
629
616
630 def normcase(self):
617 def normcase(self):
631 return ifile(path.path.normcase(self))
618 return ifile(path.path.normcase(self))
632 normcase.__doc__ = path.path.normcase.__doc__
619 normcase.__doc__ = path.path.normcase.__doc__
633
620
634 def normpath(self):
621 def normpath(self):
635 return ifile(path.path.normpath(self))
622 return ifile(path.path.normpath(self))
636 normpath.__doc__ = path.path.normpath.__doc__
623 normpath.__doc__ = path.path.normpath.__doc__
637
624
638 def realpath(self):
625 def realpath(self):
639 return ifile(path.path.realpath(self))
626 return ifile(path.path.realpath(self))
640 realpath.__doc__ = path.path.realpath.__doc__
627 realpath.__doc__ = path.path.realpath.__doc__
641
628
642 def expanduser(self):
629 def expanduser(self):
643 return ifile(path.path.expanduser(self))
630 return ifile(path.path.expanduser(self))
644 expanduser.__doc__ = path.path.expanduser.__doc__
631 expanduser.__doc__ = path.path.expanduser.__doc__
645
632
646 def expandvars(self):
633 def expandvars(self):
647 return ifile(path.path.expandvars(self))
634 return ifile(path.path.expandvars(self))
648 expandvars.__doc__ = path.path.expandvars.__doc__
635 expandvars.__doc__ = path.path.expandvars.__doc__
649
636
650 def dirname(self):
637 def dirname(self):
651 return ifile(path.path.dirname(self))
638 return ifile(path.path.dirname(self))
652 dirname.__doc__ = path.path.dirname.__doc__
639 dirname.__doc__ = path.path.dirname.__doc__
653
640
654 parent = property(dirname, None, None, path.path.parent.__doc__)
641 parent = property(dirname, None, None, path.path.parent.__doc__)
655
642
656 def splitpath(self):
643 def splitpath(self):
657 (parent, child) = path.path.splitpath(self)
644 (parent, child) = path.path.splitpath(self)
658 return (ifile(parent), child)
645 return (ifile(parent), child)
659 splitpath.__doc__ = path.path.splitpath.__doc__
646 splitpath.__doc__ = path.path.splitpath.__doc__
660
647
661 def splitdrive(self):
648 def splitdrive(self):
662 (drive, rel) = path.path.splitdrive(self)
649 (drive, rel) = path.path.splitdrive(self)
663 return (ifile(drive), rel)
650 return (ifile(drive), rel)
664 splitdrive.__doc__ = path.path.splitdrive.__doc__
651 splitdrive.__doc__ = path.path.splitdrive.__doc__
665
652
666 def splitext(self):
653 def splitext(self):
667 (filename, ext) = path.path.splitext(self)
654 (filename, ext) = path.path.splitext(self)
668 return (ifile(filename), ext)
655 return (ifile(filename), ext)
669 splitext.__doc__ = path.path.splitext.__doc__
656 splitext.__doc__ = path.path.splitext.__doc__
670
657
671 if hasattr(path.path, "splitunc"):
658 if hasattr(path.path, "splitunc"):
672 def splitunc(self):
659 def splitunc(self):
673 (unc, rest) = path.path.splitunc(self)
660 (unc, rest) = path.path.splitunc(self)
674 return (ifile(unc), rest)
661 return (ifile(unc), rest)
675 splitunc.__doc__ = path.path.splitunc.__doc__
662 splitunc.__doc__ = path.path.splitunc.__doc__
676
663
677 def _get_uncshare(self):
664 def _get_uncshare(self):
678 unc, r = os.path.splitunc(self)
665 unc, r = os.path.splitunc(self)
679 return ifile(unc)
666 return ifile(unc)
680
667
681 uncshare = property(
668 uncshare = property(
682 _get_uncshare, None, None,
669 _get_uncshare, None, None,
683 """ The UNC mount point for this path.
670 """ The UNC mount point for this path.
684 This is empty for paths on local drives. """)
671 This is empty for paths on local drives. """)
685
672
686 def joinpath(self, *args):
673 def joinpath(self, *args):
687 return ifile(path.path.joinpath(self, *args))
674 return ifile(path.path.joinpath(self, *args))
688 joinpath.__doc__ = path.path.joinpath.__doc__
675 joinpath.__doc__ = path.path.joinpath.__doc__
689
676
690 def splitall(self):
677 def splitall(self):
691 return map(ifile, path.path.splitall(self))
678 return map(ifile, path.path.splitall(self))
692 splitall.__doc__ = path.path.splitall.__doc__
679 splitall.__doc__ = path.path.splitall.__doc__
693
680
694 def relpath(self):
681 def relpath(self):
695 return ifile(path.path.relpath(self))
682 return ifile(path.path.relpath(self))
696 relpath.__doc__ = path.path.relpath.__doc__
683 relpath.__doc__ = path.path.relpath.__doc__
697
684
698 def relpathto(self, dest):
685 def relpathto(self, dest):
699 return ifile(path.path.relpathto(self, dest))
686 return ifile(path.path.relpathto(self, dest))
700 relpathto.__doc__ = path.path.relpathto.__doc__
687 relpathto.__doc__ = path.path.relpathto.__doc__
701
688
702 def listdir(self, pattern=None):
689 def listdir(self, pattern=None):
703 return [ifile(child) for child in path.path.listdir(self, pattern)]
690 return [ifile(child) for child in path.path.listdir(self, pattern)]
704 listdir.__doc__ = path.path.listdir.__doc__
691 listdir.__doc__ = path.path.listdir.__doc__
705
692
706 def dirs(self, pattern=None):
693 def dirs(self, pattern=None):
707 return [ifile(child) for child in path.path.dirs(self, pattern)]
694 return [ifile(child) for child in path.path.dirs(self, pattern)]
708 dirs.__doc__ = path.path.dirs.__doc__
695 dirs.__doc__ = path.path.dirs.__doc__
709
696
710 def files(self, pattern=None):
697 def files(self, pattern=None):
711 return [ifile(child) for child in path.path.files(self, pattern)]
698 return [ifile(child) for child in path.path.files(self, pattern)]
712 files.__doc__ = path.path.files.__doc__
699 files.__doc__ = path.path.files.__doc__
713
700
714 def walk(self, pattern=None):
701 def walk(self, pattern=None):
715 for child in path.path.walk(self, pattern):
702 for child in path.path.walk(self, pattern):
716 yield ifile(child)
703 yield ifile(child)
717 walk.__doc__ = path.path.walk.__doc__
704 walk.__doc__ = path.path.walk.__doc__
718
705
719 def walkdirs(self, pattern=None):
706 def walkdirs(self, pattern=None):
720 for child in path.path.walkdirs(self, pattern):
707 for child in path.path.walkdirs(self, pattern):
721 yield ifile(child)
708 yield ifile(child)
722 walkdirs.__doc__ = path.path.walkdirs.__doc__
709 walkdirs.__doc__ = path.path.walkdirs.__doc__
723
710
724 def walkfiles(self, pattern=None):
711 def walkfiles(self, pattern=None):
725 for child in path.path.walkfiles(self, pattern):
712 for child in path.path.walkfiles(self, pattern):
726 yield ifile(child)
713 yield ifile(child)
727 walkfiles.__doc__ = path.path.walkfiles.__doc__
714 walkfiles.__doc__ = path.path.walkfiles.__doc__
728
715
729 def glob(self, pattern):
716 def glob(self, pattern):
730 return map(ifile, path.path.glob(self, pattern))
717 return map(ifile, path.path.glob(self, pattern))
731 glob.__doc__ = path.path.glob.__doc__
718 glob.__doc__ = path.path.glob.__doc__
732
719
733 if hasattr(os, 'readlink'):
720 if hasattr(os, 'readlink'):
734 def readlink(self):
721 def readlink(self):
735 return ifile(path.path.readlink(self))
722 return ifile(path.path.readlink(self))
736 readlink.__doc__ = path.path.readlink.__doc__
723 readlink.__doc__ = path.path.readlink.__doc__
737
724
738 def readlinkabs(self):
725 def readlinkabs(self):
739 return ifile(path.path.readlinkabs(self))
726 return ifile(path.path.readlinkabs(self))
740 readlinkabs.__doc__ = path.path.readlinkabs.__doc__
727 readlinkabs.__doc__ = path.path.readlinkabs.__doc__
741
728
742 def getmode(self):
729 def getmode(self):
743 return self.stat().st_mode
730 return self.stat().st_mode
744 mode = property(getmode, None, None, "Access mode")
731 mode = property(getmode, None, None, "Access mode")
745
732
746 def gettype(self):
733 def gettype(self):
747 data = [
734 data = [
748 (stat.S_ISREG, "file"),
735 (stat.S_ISREG, "file"),
749 (stat.S_ISDIR, "dir"),
736 (stat.S_ISDIR, "dir"),
750 (stat.S_ISCHR, "chardev"),
737 (stat.S_ISCHR, "chardev"),
751 (stat.S_ISBLK, "blockdev"),
738 (stat.S_ISBLK, "blockdev"),
752 (stat.S_ISFIFO, "fifo"),
739 (stat.S_ISFIFO, "fifo"),
753 (stat.S_ISLNK, "symlink"),
740 (stat.S_ISLNK, "symlink"),
754 (stat.S_ISSOCK,"socket"),
741 (stat.S_ISSOCK,"socket"),
755 ]
742 ]
756 lstat = self.lstat()
743 lstat = self.lstat()
757 if lstat is not None:
744 if lstat is not None:
758 types = set([text for (func, text) in data if func(lstat.st_mode)])
745 types = set([text for (func, text) in data if func(lstat.st_mode)])
759 else:
746 else:
760 types = set()
747 types = set()
761 m = self.mode
748 m = self.mode
762 types.update([text for (func, text) in data if func(m)])
749 types.update([text for (func, text) in data if func(m)])
763 return ", ".join(types)
750 return ", ".join(types)
764 type = property(gettype, None, None, "file type (file, directory, link, etc.)")
751 type = property(gettype, None, None, "file type (file, directory, link, etc.)")
765
752
766 def getmodestr(self):
753 def getmodestr(self):
767 m = self.mode
754 m = self.mode
768 data = [
755 data = [
769 (stat.S_IRUSR, "-r"),
756 (stat.S_IRUSR, "-r"),
770 (stat.S_IWUSR, "-w"),
757 (stat.S_IWUSR, "-w"),
771 (stat.S_IXUSR, "-x"),
758 (stat.S_IXUSR, "-x"),
772 (stat.S_IRGRP, "-r"),
759 (stat.S_IRGRP, "-r"),
773 (stat.S_IWGRP, "-w"),
760 (stat.S_IWGRP, "-w"),
774 (stat.S_IXGRP, "-x"),
761 (stat.S_IXGRP, "-x"),
775 (stat.S_IROTH, "-r"),
762 (stat.S_IROTH, "-r"),
776 (stat.S_IWOTH, "-w"),
763 (stat.S_IWOTH, "-w"),
777 (stat.S_IXOTH, "-x"),
764 (stat.S_IXOTH, "-x"),
778 ]
765 ]
779 return "".join([text[bool(m&bit)] for (bit, text) in data])
766 return "".join([text[bool(m&bit)] for (bit, text) in data])
780
767
781 modestr = property(getmodestr, None, None, "Access mode as string")
768 modestr = property(getmodestr, None, None, "Access mode as string")
782
769
783 def getblocks(self):
770 def getblocks(self):
784 return self.stat().st_blocks
771 return self.stat().st_blocks
785 blocks = property(getblocks, None, None, "File size in blocks")
772 blocks = property(getblocks, None, None, "File size in blocks")
786
773
787 def getblksize(self):
774 def getblksize(self):
788 return self.stat().st_blksize
775 return self.stat().st_blksize
789 blksize = property(getblksize, None, None, "Filesystem block size")
776 blksize = property(getblksize, None, None, "Filesystem block size")
790
777
791 def getdev(self):
778 def getdev(self):
792 return self.stat().st_dev
779 return self.stat().st_dev
793 dev = property(getdev)
780 dev = property(getdev)
794
781
795 def getnlink(self):
782 def getnlink(self):
796 return self.stat().st_nlink
783 return self.stat().st_nlink
797 nlink = property(getnlink, None, None, "Number of links")
784 nlink = property(getnlink, None, None, "Number of links")
798
785
799 def getuid(self):
786 def getuid(self):
800 return self.stat().st_uid
787 return self.stat().st_uid
801 uid = property(getuid, None, None, "User id of file owner")
788 uid = property(getuid, None, None, "User id of file owner")
802
789
803 def getgid(self):
790 def getgid(self):
804 return self.stat().st_gid
791 return self.stat().st_gid
805 gid = property(getgid, None, None, "Group id of file owner")
792 gid = property(getgid, None, None, "Group id of file owner")
806
793
807 def getowner(self):
794 def getowner(self):
808 stat = self.stat()
795 stat = self.stat()
809 try:
796 try:
810 return pwd.getpwuid(stat.st_uid).pw_name
797 return pwd.getpwuid(stat.st_uid).pw_name
811 except KeyError:
798 except KeyError:
812 return stat.st_uid
799 return stat.st_uid
813 owner = property(getowner, None, None, "Owner name (or id)")
800 owner = property(getowner, None, None, "Owner name (or id)")
814
801
815 def getgroup(self):
802 def getgroup(self):
816 stat = self.stat()
803 stat = self.stat()
817 try:
804 try:
818 return grp.getgrgid(stat.st_gid).gr_name
805 return grp.getgrgid(stat.st_gid).gr_name
819 except KeyError:
806 except KeyError:
820 return stat.st_gid
807 return stat.st_gid
821 group = property(getgroup, None, None, "Group name (or id)")
808 group = property(getgroup, None, None, "Group name (or id)")
822
809
823 def getadate(self):
810 def getadate(self):
824 return datetime.datetime.utcfromtimestamp(self.atime)
811 return datetime.datetime.utcfromtimestamp(self.atime)
825 adate = property(getadate, None, None, "Access date")
812 adate = property(getadate, None, None, "Access date")
826
813
827 def getcdate(self):
814 def getcdate(self):
828 return datetime.datetime.utcfromtimestamp(self.ctime)
815 return datetime.datetime.utcfromtimestamp(self.ctime)
829 cdate = property(getcdate, None, None, "Creation date")
816 cdate = property(getcdate, None, None, "Creation date")
830
817
831 def getmdate(self):
818 def getmdate(self):
832 return datetime.datetime.utcfromtimestamp(self.mtime)
819 return datetime.datetime.utcfromtimestamp(self.mtime)
833 mdate = property(getmdate, None, None, "Modification date")
820 mdate = property(getmdate, None, None, "Modification date")
834
821
835 def getmimetype(self):
822 def getmimetype(self):
836 return mimetypes.guess_type(self.basename())[0]
823 return mimetypes.guess_type(self.basename())[0]
837 mimetype = property(getmimetype, None, None, "MIME type")
824 mimetype = property(getmimetype, None, None, "MIME type")
838
825
839 def getencoding(self):
826 def getencoding(self):
840 return mimetypes.guess_type(self.basename())[1]
827 return mimetypes.guess_type(self.basename())[1]
841 encoding = property(getencoding, None, None, "Compression")
828 encoding = property(getencoding, None, None, "Compression")
842
829
843 def __repr__(self):
830 def __repr__(self):
844 return "ifile(%s)" % path._base.__repr__(self)
831 return "ifile(%s)" % path._base.__repr__(self)
845
832
846 defaultattrs = (None, "type", "size", "modestr", "owner", "group", "mdate")
833 defaultattrs = (None, "type", "size", "modestr", "owner", "group", "mdate")
847
834
848 def __xattrs__(self, mode):
835 def __xattrs__(self, mode):
849 if mode == "detail":
836 if mode == "detail":
850 return (
837 return (
851 "name", "basename()", "abspath()", "realpath()",
838 "name", "basename()", "abspath()", "realpath()",
852 "type", "mode", "modestr", "stat()", "lstat()",
839 "type", "mode", "modestr", "stat()", "lstat()",
853 "uid", "gid", "owner", "group", "dev", "nlink",
840 "uid", "gid", "owner", "group", "dev", "nlink",
854 "ctime", "mtime", "atime", "cdate", "mdate", "adate",
841 "ctime", "mtime", "atime", "cdate", "mdate", "adate",
855 "size", "blocks", "blksize", "isdir()", "islink()",
842 "size", "blocks", "blksize", "isdir()", "islink()",
856 "mimetype", "encoding"
843 "mimetype", "encoding"
857 )
844 )
858 return self.defaultattrs
845 return self.defaultattrs
859
846
860 def __xrepr__(self, mode):
847 def __xrepr__(self, mode):
861 yield (-1, True)
862 try:
848 try:
863 if self.isdir():
849 if self.isdir():
864 name = "idir"
850 name = "idir"
865 style = astyle.style_dir
851 style = astyle.style_dir
866 else:
852 else:
867 name = "ifile"
853 name = "ifile"
868 style = astyle.style_file
854 style = astyle.style_file
869 except IOError:
855 except IOError:
870 name = "ifile"
856 name = "ifile"
871 style = astyle.style_default
857 style = astyle.style_default
872 if mode == "cell" or mode in "header" or mode == "footer":
858 if mode == "cell" or mode in "header" or mode == "footer":
873 abspath = repr(path._base(self.normpath()))
859 abspath = repr(path._base(self.normpath()))
874 if abspath.startswith("u"):
860 if abspath.startswith("u"):
875 abspath = abspath[2:-1]
861 abspath = abspath[2:-1]
876 else:
862 else:
877 abspath = abspath[1:-1]
863 abspath = abspath[1:-1]
878 if mode == "cell":
864 if mode == "cell":
879 yield (style, abspath)
865 yield (style, abspath)
880 else:
866 else:
881 yield (style, "%s(%s)" % (name, abspath))
867 yield (style, "%s(%s)" % (name, abspath))
882 else:
868 else:
883 yield (style, repr(self))
869 yield (style, repr(self))
884
870
885 def __xiter__(self, mode):
871 def __xiter__(self, mode):
886 if self.isdir():
872 if self.isdir():
887 yield iparentdir(self / os.pardir)
873 yield iparentdir(self / os.pardir)
888 for child in sorted(self.listdir()):
874 for child in sorted(self.listdir()):
889 yield child
875 yield child
890 else:
876 else:
891 f = self.open("rb")
877 f = self.open("rb")
892 for line in f:
878 for line in f:
893 yield line
879 yield line
894 f.close()
880 f.close()
895
881
896
882
897 class iparentdir(ifile):
883 class iparentdir(ifile):
898 def __xrepr__(self, mode):
884 def __xrepr__(self, mode):
899 yield (-1, True)
900 if mode == "cell":
885 if mode == "cell":
901 yield (astyle.style_dir, os.pardir)
886 yield (astyle.style_dir, os.pardir)
902 else:
887 else:
903 for part in ifile.__xrepr__(self, mode):
888 for part in ifile.__xrepr__(self, mode):
904 yield part
889 yield part
905
890
906
891
907 class ils(Table):
892 class ils(Table):
908 """
893 """
909 List the current (or a specific) directory.
894 List the current (or a specific) directory.
910
895
911 Examples:
896 Examples:
912
897
913 >>> ils
898 >>> ils
914 >>> ils("/usr/local/lib/python2.4")
899 >>> ils("/usr/local/lib/python2.4")
915 >>> ils("~")
900 >>> ils("~")
916 """
901 """
917 def __init__(self, base=os.curdir):
902 def __init__(self, base=os.curdir):
918 self.base = os.path.expanduser(base)
903 self.base = os.path.expanduser(base)
919
904
920 def __xiter__(self, mode):
905 def __xiter__(self, mode):
921 return xiter(ifile(self.base), mode)
906 return xiter(ifile(self.base), mode)
922
907
923 def __xrepr__(self, mode):
908 def __xrepr__(self, mode):
924 return ifile(self.base).__xrepr__(mode)
909 return ifile(self.base).__xrepr__(mode)
925
910
926 def __repr__(self):
911 def __repr__(self):
927 return "%s.%s(%r)" % \
912 return "%s.%s(%r)" % \
928 (self.__class__.__module__, self.__class__.__name__, self.base)
913 (self.__class__.__module__, self.__class__.__name__, self.base)
929
914
930
915
931 class iglob(Table):
916 class iglob(Table):
932 """
917 """
933 List all files and directories matching a specified pattern.
918 List all files and directories matching a specified pattern.
934 (See ``glob.glob()`` for more info.).
919 (See ``glob.glob()`` for more info.).
935
920
936 Examples:
921 Examples:
937
922
938 >>> iglob("*.py")
923 >>> iglob("*.py")
939 """
924 """
940 def __init__(self, glob):
925 def __init__(self, glob):
941 self.glob = glob
926 self.glob = glob
942
927
943 def __xiter__(self, mode):
928 def __xiter__(self, mode):
944 for name in glob.glob(self.glob):
929 for name in glob.glob(self.glob):
945 yield ifile(name)
930 yield ifile(name)
946
931
947 def __xrepr__(self, mode):
932 def __xrepr__(self, mode):
948 yield (-1, True)
949 if mode == "header" or mode == "footer" or mode == "cell":
933 if mode == "header" or mode == "footer" or mode == "cell":
950 yield (astyle.style_default,
934 yield (astyle.style_default,
951 "%s(%r)" % (self.__class__.__name__, self.glob))
935 "%s(%r)" % (self.__class__.__name__, self.glob))
952 else:
936 else:
953 yield (astyle.style_default, repr(self))
937 yield (astyle.style_default, repr(self))
954
938
955 def __repr__(self):
939 def __repr__(self):
956 return "%s.%s(%r)" % \
940 return "%s.%s(%r)" % \
957 (self.__class__.__module__, self.__class__.__name__, self.glob)
941 (self.__class__.__module__, self.__class__.__name__, self.glob)
958
942
959
943
960 class iwalk(Table):
944 class iwalk(Table):
961 """
945 """
962 List all files and directories in a directory and it's subdirectory.
946 List all files and directories in a directory and it's subdirectory.
963
947
964 >>> iwalk
948 >>> iwalk
965 >>> iwalk("/usr/local/lib/python2.4")
949 >>> iwalk("/usr/local/lib/python2.4")
966 >>> iwalk("~")
950 >>> iwalk("~")
967 """
951 """
968 def __init__(self, base=os.curdir, dirs=True, files=True):
952 def __init__(self, base=os.curdir, dirs=True, files=True):
969 self.base = os.path.expanduser(base)
953 self.base = os.path.expanduser(base)
970 self.dirs = dirs
954 self.dirs = dirs
971 self.files = files
955 self.files = files
972
956
973 def __xiter__(self, mode):
957 def __xiter__(self, mode):
974 for (dirpath, dirnames, filenames) in os.walk(self.base):
958 for (dirpath, dirnames, filenames) in os.walk(self.base):
975 if self.dirs:
959 if self.dirs:
976 for name in sorted(dirnames):
960 for name in sorted(dirnames):
977 yield ifile(os.path.join(dirpath, name))
961 yield ifile(os.path.join(dirpath, name))
978 if self.files:
962 if self.files:
979 for name in sorted(filenames):
963 for name in sorted(filenames):
980 yield ifile(os.path.join(dirpath, name))
964 yield ifile(os.path.join(dirpath, name))
981
965
982 def __xrepr__(self, mode):
966 def __xrepr__(self, mode):
983 yield (-1, True)
984 if mode == "header" or mode == "footer" or mode == "cell":
967 if mode == "header" or mode == "footer" or mode == "cell":
985 yield (astyle.style_default,
968 yield (astyle.style_default,
986 "%s(%r)" % (self.__class__.__name__, self.base))
969 "%s(%r)" % (self.__class__.__name__, self.base))
987 else:
970 else:
988 yield (astyle.style_default, repr(self))
971 yield (astyle.style_default, repr(self))
989
972
990 def __repr__(self):
973 def __repr__(self):
991 return "%s.%s(%r)" % \
974 return "%s.%s(%r)" % \
992 (self.__class__.__module__, self.__class__.__name__, self.base)
975 (self.__class__.__module__, self.__class__.__name__, self.base)
993
976
994
977
995 class ipwdentry(object):
978 class ipwdentry(object):
996 """
979 """
997 ``ipwdentry`` objects encapsulate entries in the Unix user account and
980 ``ipwdentry`` objects encapsulate entries in the Unix user account and
998 password database.
981 password database.
999 """
982 """
1000 def __init__(self, id):
983 def __init__(self, id):
1001 self._id = id
984 self._id = id
1002 self._entry = None
985 self._entry = None
1003
986
1004 def _getentry(self):
987 def _getentry(self):
1005 if self._entry is None:
988 if self._entry is None:
1006 if isinstance(self._id, basestring):
989 if isinstance(self._id, basestring):
1007 self._entry = pwd.getpwnam(self._id)
990 self._entry = pwd.getpwnam(self._id)
1008 else:
991 else:
1009 self._entry = pwd.getpwuid(self._id)
992 self._entry = pwd.getpwuid(self._id)
1010 return self._entry
993 return self._entry
1011
994
1012 def getname(self):
995 def getname(self):
1013 if isinstance(self._id, basestring):
996 if isinstance(self._id, basestring):
1014 return self._id
997 return self._id
1015 else:
998 else:
1016 return self._getentry().pw_name
999 return self._getentry().pw_name
1017 name = property(getname, None, None, "User name")
1000 name = property(getname, None, None, "User name")
1018
1001
1019 def getpasswd(self):
1002 def getpasswd(self):
1020 return self._getentry().pw_passwd
1003 return self._getentry().pw_passwd
1021 passwd = property(getpasswd, None, None, "Password")
1004 passwd = property(getpasswd, None, None, "Password")
1022
1005
1023 def getuid(self):
1006 def getuid(self):
1024 if isinstance(self._id, basestring):
1007 if isinstance(self._id, basestring):
1025 return self._getentry().pw_uid
1008 return self._getentry().pw_uid
1026 else:
1009 else:
1027 return self._id
1010 return self._id
1028 uid = property(getuid, None, None, "User id")
1011 uid = property(getuid, None, None, "User id")
1029
1012
1030 def getgid(self):
1013 def getgid(self):
1031 return self._getentry().pw_gid
1014 return self._getentry().pw_gid
1032 gid = property(getgid, None, None, "Primary group id")
1015 gid = property(getgid, None, None, "Primary group id")
1033
1016
1034 def getgroup(self):
1017 def getgroup(self):
1035 return igrpentry(self.gid)
1018 return igrpentry(self.gid)
1036 group = property(getgroup, None, None, "Group")
1019 group = property(getgroup, None, None, "Group")
1037
1020
1038 def getgecos(self):
1021 def getgecos(self):
1039 return self._getentry().pw_gecos
1022 return self._getentry().pw_gecos
1040 gecos = property(getgecos, None, None, "Information (e.g. full user name)")
1023 gecos = property(getgecos, None, None, "Information (e.g. full user name)")
1041
1024
1042 def getdir(self):
1025 def getdir(self):
1043 return self._getentry().pw_dir
1026 return self._getentry().pw_dir
1044 dir = property(getdir, None, None, "$HOME directory")
1027 dir = property(getdir, None, None, "$HOME directory")
1045
1028
1046 def getshell(self):
1029 def getshell(self):
1047 return self._getentry().pw_shell
1030 return self._getentry().pw_shell
1048 shell = property(getshell, None, None, "Login shell")
1031 shell = property(getshell, None, None, "Login shell")
1049
1032
1050 def __xattrs__(self, mode):
1033 def __xattrs__(self, mode):
1051 return ("name", "passwd", "uid", "gid", "gecos", "dir", "shell")
1034 return ("name", "passwd", "uid", "gid", "gecos", "dir", "shell")
1052
1035
1053 def __repr__(self):
1036 def __repr__(self):
1054 return "%s.%s(%r)" % \
1037 return "%s.%s(%r)" % \
1055 (self.__class__.__module__, self.__class__.__name__, self._id)
1038 (self.__class__.__module__, self.__class__.__name__, self._id)
1056
1039
1057
1040
1058 class ipwd(Table):
1041 class ipwd(Table):
1059 """
1042 """
1060 List all entries in the Unix user account and password database.
1043 List all entries in the Unix user account and password database.
1061
1044
1062 Example:
1045 Example:
1063
1046
1064 >>> ipwd | isort("uid")
1047 >>> ipwd | isort("uid")
1065 """
1048 """
1066 def __iter__(self):
1049 def __iter__(self):
1067 for entry in pwd.getpwall():
1050 for entry in pwd.getpwall():
1068 yield ipwdentry(entry.pw_name)
1051 yield ipwdentry(entry.pw_name)
1069
1052
1070 def __xrepr__(self, mode):
1053 def __xrepr__(self, mode):
1071 yield (-1, True)
1072 if mode == "header" or mode == "footer" or mode == "cell":
1054 if mode == "header" or mode == "footer" or mode == "cell":
1073 yield (astyle.style_default, "%s()" % self.__class__.__name__)
1055 yield (astyle.style_default, "%s()" % self.__class__.__name__)
1074 else:
1056 else:
1075 yield (astyle.style_default, repr(self))
1057 yield (astyle.style_default, repr(self))
1076
1058
1077
1059
1078 class igrpentry(object):
1060 class igrpentry(object):
1079 """
1061 """
1080 ``igrpentry`` objects encapsulate entries in the Unix group database.
1062 ``igrpentry`` objects encapsulate entries in the Unix group database.
1081 """
1063 """
1082 def __init__(self, id):
1064 def __init__(self, id):
1083 self._id = id
1065 self._id = id
1084 self._entry = None
1066 self._entry = None
1085
1067
1086 def _getentry(self):
1068 def _getentry(self):
1087 if self._entry is None:
1069 if self._entry is None:
1088 if isinstance(self._id, basestring):
1070 if isinstance(self._id, basestring):
1089 self._entry = grp.getgrnam(self._id)
1071 self._entry = grp.getgrnam(self._id)
1090 else:
1072 else:
1091 self._entry = grp.getgrgid(self._id)
1073 self._entry = grp.getgrgid(self._id)
1092 return self._entry
1074 return self._entry
1093
1075
1094 def getname(self):
1076 def getname(self):
1095 if isinstance(self._id, basestring):
1077 if isinstance(self._id, basestring):
1096 return self._id
1078 return self._id
1097 else:
1079 else:
1098 return self._getentry().gr_name
1080 return self._getentry().gr_name
1099 name = property(getname, None, None, "Group name")
1081 name = property(getname, None, None, "Group name")
1100
1082
1101 def getpasswd(self):
1083 def getpasswd(self):
1102 return self._getentry().gr_passwd
1084 return self._getentry().gr_passwd
1103 passwd = property(getpasswd, None, None, "Password")
1085 passwd = property(getpasswd, None, None, "Password")
1104
1086
1105 def getgid(self):
1087 def getgid(self):
1106 if isinstance(self._id, basestring):
1088 if isinstance(self._id, basestring):
1107 return self._getentry().gr_gid
1089 return self._getentry().gr_gid
1108 else:
1090 else:
1109 return self._id
1091 return self._id
1110 gid = property(getgid, None, None, "Group id")
1092 gid = property(getgid, None, None, "Group id")
1111
1093
1112 def getmem(self):
1094 def getmem(self):
1113 return self._getentry().gr_mem
1095 return self._getentry().gr_mem
1114 mem = property(getmem, None, None, "Members")
1096 mem = property(getmem, None, None, "Members")
1115
1097
1116 def __xattrs__(self, mode):
1098 def __xattrs__(self, mode):
1117 return ("name", "passwd", "gid", "mem")
1099 return ("name", "passwd", "gid", "mem")
1118
1100
1119 def __xrepr__(self, mode):
1101 def __xrepr__(self, mode):
1120 yield (-1, True)
1121 if mode == "header" or mode == "footer" or mode == "cell":
1102 if mode == "header" or mode == "footer" or mode == "cell":
1122 yield (astyle.style_default, "group ")
1103 yield (astyle.style_default, "group ")
1123 try:
1104 try:
1124 yield (astyle.style_default, self.name)
1105 yield (astyle.style_default, self.name)
1125 except KeyError:
1106 except KeyError:
1126 if isinstance(self._id, basestring):
1107 if isinstance(self._id, basestring):
1127 yield (astyle.style_default, self.name_id)
1108 yield (astyle.style_default, self.name_id)
1128 else:
1109 else:
1129 yield (astyle.style_type_number, str(self._id))
1110 yield (astyle.style_type_number, str(self._id))
1130 else:
1111 else:
1131 yield (astyle.style_default, repr(self))
1112 yield (astyle.style_default, repr(self))
1132
1113
1133 def __xiter__(self, mode):
1114 def __xiter__(self, mode):
1134 for member in self.mem:
1115 for member in self.mem:
1135 yield ipwdentry(member)
1116 yield ipwdentry(member)
1136
1117
1137 def __repr__(self):
1118 def __repr__(self):
1138 return "%s.%s(%r)" % \
1119 return "%s.%s(%r)" % \
1139 (self.__class__.__module__, self.__class__.__name__, self._id)
1120 (self.__class__.__module__, self.__class__.__name__, self._id)
1140
1121
1141
1122
1142 class igrp(Table):
1123 class igrp(Table):
1143 """
1124 """
1144 This ``Table`` lists all entries in the Unix group database.
1125 This ``Table`` lists all entries in the Unix group database.
1145 """
1126 """
1146 def __xiter__(self, mode):
1127 def __xiter__(self, mode):
1147 for entry in grp.getgrall():
1128 for entry in grp.getgrall():
1148 yield igrpentry(entry.gr_name)
1129 yield igrpentry(entry.gr_name)
1149
1130
1150 def __xrepr__(self, mode):
1131 def __xrepr__(self, mode):
1151 yield (-1, False)
1152 if mode == "header" or mode == "footer":
1132 if mode == "header" or mode == "footer":
1153 yield (astyle.style_default, "%s()" % self.__class__.__name__)
1133 yield (astyle.style_default, "%s()" % self.__class__.__name__)
1154 else:
1134 else:
1155 yield (astyle.style_default, repr(self))
1135 yield (astyle.style_default, repr(self))
1156
1136
1157
1137
1158 class Fields(object):
1138 class Fields(object):
1159 def __init__(self, fieldnames, **fields):
1139 def __init__(self, fieldnames, **fields):
1160 self.__fieldnames = fieldnames
1140 self.__fieldnames = fieldnames
1161 for (key, value) in fields.iteritems():
1141 for (key, value) in fields.iteritems():
1162 setattr(self, key, value)
1142 setattr(self, key, value)
1163
1143
1164 def __xattrs__(self, mode):
1144 def __xattrs__(self, mode):
1165 return self.__fieldnames
1145 return self.__fieldnames
1166
1146
1167 def __xrepr__(self, mode):
1147 def __xrepr__(self, mode):
1168 yield (-1, False)
1148 yield (-1, False)
1169 if mode == "header" or mode == "cell":
1149 if mode == "header" or mode == "cell":
1170 yield (astyle.style_default, self.__class__.__name__)
1150 yield (astyle.style_default, self.__class__.__name__)
1171 yield (astyle.style_default, "(")
1151 yield (astyle.style_default, "(")
1172 for (i, f) in enumerate(self.__fieldnames):
1152 for (i, f) in enumerate(self.__fieldnames):
1173 if i:
1153 if i:
1174 yield (astyle.style_default, ", ")
1154 yield (astyle.style_default, ", ")
1175 yield (astyle.style_default, f)
1155 yield (astyle.style_default, f)
1176 yield (astyle.style_default, "=")
1156 yield (astyle.style_default, "=")
1177 for part in xrepr(getattr(self, f), "default"):
1157 for part in xrepr(getattr(self, f), "default"):
1178 yield part
1158 yield part
1179 yield (astyle.style_default, ")")
1159 yield (astyle.style_default, ")")
1180 elif mode == "footer":
1160 elif mode == "footer":
1181 yield (astyle.style_default, self.__class__.__name__)
1161 yield (astyle.style_default, self.__class__.__name__)
1182 yield (astyle.style_default, "(")
1162 yield (astyle.style_default, "(")
1183 for (i, f) in enumerate(self.__fieldnames):
1163 for (i, f) in enumerate(self.__fieldnames):
1184 if i:
1164 if i:
1185 yield (astyle.style_default, ", ")
1165 yield (astyle.style_default, ", ")
1186 yield (astyle.style_default, f)
1166 yield (astyle.style_default, f)
1187 yield (astyle.style_default, ")")
1167 yield (astyle.style_default, ")")
1188 else:
1168 else:
1189 yield (astyle.style_default, repr(self))
1169 yield (astyle.style_default, repr(self))
1190
1170
1191
1171
1192 class FieldTable(Table, list):
1172 class FieldTable(Table, list):
1193 def __init__(self, *fields):
1173 def __init__(self, *fields):
1194 Table.__init__(self)
1174 Table.__init__(self)
1195 list.__init__(self)
1175 list.__init__(self)
1196 self.fields = fields
1176 self.fields = fields
1197
1177
1198 def add(self, **fields):
1178 def add(self, **fields):
1199 self.append(Fields(self.fields, **fields))
1179 self.append(Fields(self.fields, **fields))
1200
1180
1201 def __xiter__(self, mode):
1181 def __xiter__(self, mode):
1202 return list.__iter__(self)
1182 return list.__iter__(self)
1203
1183
1204 def __xrepr__(self, mode):
1184 def __xrepr__(self, mode):
1205 yield (-1, False)
1185 yield (-1, False)
1206 if mode == "header" or mode == "footer":
1186 if mode == "header" or mode == "footer":
1207 yield (astyle.style_default, self.__class__.__name__)
1187 yield (astyle.style_default, self.__class__.__name__)
1208 yield (astyle.style_default, "(")
1188 yield (astyle.style_default, "(")
1209 for (i, f) in enumerate(self.__fieldnames):
1189 for (i, f) in enumerate(self.__fieldnames):
1210 if i:
1190 if i:
1211 yield (astyle.style_default, ", ")
1191 yield (astyle.style_default, ", ")
1212 yield (astyle.style_default, f)
1192 yield (astyle.style_default, f)
1213 yield (astyle.style_default, ")")
1193 yield (astyle.style_default, ")")
1214 else:
1194 else:
1215 yield (astyle.style_default, repr(self))
1195 yield (astyle.style_default, repr(self))
1216
1196
1217 def __repr__(self):
1197 def __repr__(self):
1218 return "<%s.%s object with fields=%r at 0x%x>" % \
1198 return "<%s.%s object with fields=%r at 0x%x>" % \
1219 (self.__class__.__module__, self.__class__.__name__,
1199 (self.__class__.__module__, self.__class__.__name__,
1220 ", ".join(map(repr, self.fields)), id(self))
1200 ", ".join(map(repr, self.fields)), id(self))
1221
1201
1222
1202
1223 class List(list):
1203 class List(list):
1224 def __xattrs__(self, mode):
1204 def __xattrs__(self, mode):
1225 return xrange(len(self))
1205 return xrange(len(self))
1226
1206
1227 def __xrepr__(self, mode):
1207 def __xrepr__(self, mode):
1228 yield (-1, False)
1208 yield (-1, False)
1229 if mode == "header" or mode == "cell" or mode == "footer" or mode == "default":
1209 if mode == "header" or mode == "cell" or mode == "footer" or mode == "default":
1230 yield (astyle.style_default, self.__class__.__name__)
1210 yield (astyle.style_default, self.__class__.__name__)
1231 yield (astyle.style_default, "(")
1211 yield (astyle.style_default, "(")
1232 for (i, item) in enumerate(self):
1212 for (i, item) in enumerate(self):
1233 if i:
1213 if i:
1234 yield (astyle.style_default, ", ")
1214 yield (astyle.style_default, ", ")
1235 for part in xrepr(item, "default"):
1215 for part in xrepr(item, "default"):
1236 yield part
1216 yield part
1237 yield (astyle.style_default, ")")
1217 yield (astyle.style_default, ")")
1238 else:
1218 else:
1239 yield (astyle.style_default, repr(self))
1219 yield (astyle.style_default, repr(self))
1240
1220
1241
1221
1242 class ienv(Table):
1222 class ienv(Table):
1243 """
1223 """
1244 List environment variables.
1224 List environment variables.
1245
1225
1246 Example:
1226 Example:
1247
1227
1248 >>> ienv
1228 >>> ienv
1249 """
1229 """
1250
1230
1251 def __xiter__(self, mode):
1231 def __xiter__(self, mode):
1252 fields = ("key", "value")
1232 fields = ("key", "value")
1253 for (key, value) in os.environ.iteritems():
1233 for (key, value) in os.environ.iteritems():
1254 yield Fields(fields, key=key, value=value)
1234 yield Fields(fields, key=key, value=value)
1255
1235
1256 def __xrepr__(self, mode):
1236 def __xrepr__(self, mode):
1257 yield (-1, True)
1258 if mode == "header" or mode == "cell":
1237 if mode == "header" or mode == "cell":
1259 yield (astyle.style_default, "%s()" % self.__class__.__name__)
1238 yield (astyle.style_default, "%s()" % self.__class__.__name__)
1260 else:
1239 else:
1261 yield (astyle.style_default, repr(self))
1240 yield (astyle.style_default, repr(self))
1262
1241
1263
1242
1264 class icsv(Pipe):
1243 class icsv(Pipe):
1265 """
1244 """
1266 This ``Pipe`` lists turn the input (with must be a pipe outputting lines
1245 This ``Pipe`` lists turn the input (with must be a pipe outputting lines
1267 or an ``ifile``) into lines of CVS columns.
1246 or an ``ifile``) into lines of CVS columns.
1268 """
1247 """
1269 def __init__(self, **csvargs):
1248 def __init__(self, **csvargs):
1270 """
1249 """
1271 Create an ``icsv`` object. ``cvsargs`` will be passed through as
1250 Create an ``icsv`` object. ``cvsargs`` will be passed through as
1272 keyword arguments to ``cvs.reader()``.
1251 keyword arguments to ``cvs.reader()``.
1273 """
1252 """
1274 self.csvargs = csvargs
1253 self.csvargs = csvargs
1275
1254
1276 def __xiter__(self, mode):
1255 def __xiter__(self, mode):
1277 input = self.input
1256 input = self.input
1278 if isinstance(input, ifile):
1257 if isinstance(input, ifile):
1279 input = input.open("rb")
1258 input = input.open("rb")
1280 reader = csv.reader(input, **self.csvargs)
1259 reader = csv.reader(input, **self.csvargs)
1281 for line in reader:
1260 for line in reader:
1282 yield List(line)
1261 yield List(line)
1283
1262
1284 def __xrepr__(self, mode):
1263 def __xrepr__(self, mode):
1285 yield (-1, False)
1264 yield (-1, False)
1286 if mode == "header" or mode == "footer":
1265 if mode == "header" or mode == "footer":
1287 input = getattr(self, "input", None)
1266 input = getattr(self, "input", None)
1288 if input is not None:
1267 if input is not None:
1289 for part in xrepr(input, mode):
1268 for part in xrepr(input, mode):
1290 yield part
1269 yield part
1291 yield (astyle.style_default, " | ")
1270 yield (astyle.style_default, " | ")
1292 yield (astyle.style_default, "%s(" % self.__class__.__name__)
1271 yield (astyle.style_default, "%s(" % self.__class__.__name__)
1293 for (i, (name, value)) in enumerate(self.csvargs.iteritems()):
1272 for (i, (name, value)) in enumerate(self.csvargs.iteritems()):
1294 if i:
1273 if i:
1295 yield (astyle.style_default, ", ")
1274 yield (astyle.style_default, ", ")
1296 yield (astyle.style_default, name)
1275 yield (astyle.style_default, name)
1297 yield (astyle.style_default, "=")
1276 yield (astyle.style_default, "=")
1298 for part in xrepr(value, "default"):
1277 for part in xrepr(value, "default"):
1299 yield part
1278 yield part
1300 yield (astyle.style_default, ")")
1279 yield (astyle.style_default, ")")
1301 else:
1280 else:
1302 yield (astyle.style_default, repr(self))
1281 yield (astyle.style_default, repr(self))
1303
1282
1304 def __repr__(self):
1283 def __repr__(self):
1305 args = ", ".join(["%s=%r" % item for item in self.csvargs.iteritems()])
1284 args = ", ".join(["%s=%r" % item for item in self.csvargs.iteritems()])
1306 return "<%s.%s %s at 0x%x>" % \
1285 return "<%s.%s %s at 0x%x>" % \
1307 (self.__class__.__module__, self.__class__.__name__, args, id(self))
1286 (self.__class__.__module__, self.__class__.__name__, args, id(self))
1308
1287
1309
1288
1310 class ix(Table):
1289 class ix(Table):
1311 """
1290 """
1312 Execute a system command and list its output as lines
1291 Execute a system command and list its output as lines
1313 (similar to ``os.popen()``).
1292 (similar to ``os.popen()``).
1314
1293
1315 Examples:
1294 Examples:
1316
1295
1317 >>> ix("ps x")
1296 >>> ix("ps x")
1318 >>> ix("find .") | ifile
1297 >>> ix("find .") | ifile
1319 """
1298 """
1320 def __init__(self, cmd):
1299 def __init__(self, cmd):
1321 self.cmd = cmd
1300 self.cmd = cmd
1322 self._pipe = None
1301 self._pipe = None
1323
1302
1324 def __xiter__(self, mode):
1303 def __xiter__(self, mode):
1325 self._pipe = os.popen(self.cmd)
1304 self._pipe = os.popen(self.cmd)
1326 for l in self._pipe:
1305 for l in self._pipe:
1327 yield l.rstrip("\r\n")
1306 yield l.rstrip("\r\n")
1328 self._pipe.close()
1307 self._pipe.close()
1329 self._pipe = None
1308 self._pipe = None
1330
1309
1331 def __del__(self):
1310 def __del__(self):
1332 if self._pipe is not None and not self._pipe.closed:
1311 if self._pipe is not None and not self._pipe.closed:
1333 self._pipe.close()
1312 self._pipe.close()
1334 self._pipe = None
1313 self._pipe = None
1335
1314
1336 def __xrepr__(self, mode):
1315 def __xrepr__(self, mode):
1337 yield (-1, True)
1338 if mode == "header" or mode == "footer":
1316 if mode == "header" or mode == "footer":
1339 yield (astyle.style_default,
1317 yield (astyle.style_default,
1340 "%s(%r)" % (self.__class__.__name__, self.cmd))
1318 "%s(%r)" % (self.__class__.__name__, self.cmd))
1341 else:
1319 else:
1342 yield (astyle.style_default, repr(self))
1320 yield (astyle.style_default, repr(self))
1343
1321
1344 def __repr__(self):
1322 def __repr__(self):
1345 return "%s.%s(%r)" % \
1323 return "%s.%s(%r)" % \
1346 (self.__class__.__module__, self.__class__.__name__, self.cmd)
1324 (self.__class__.__module__, self.__class__.__name__, self.cmd)
1347
1325
1348
1326
1349 class ifilter(Pipe):
1327 class ifilter(Pipe):
1350 """
1328 """
1351 Filter an input pipe. Only objects where an expression evaluates to true
1329 Filter an input pipe. Only objects where an expression evaluates to true
1352 (and doesn't raise an exception) are listed.
1330 (and doesn't raise an exception) are listed.
1353
1331
1354 Examples:
1332 Examples:
1355
1333
1356 >>> ils | ifilter("_.isfile() and size>1000")
1334 >>> ils | ifilter("_.isfile() and size>1000")
1357 >>> igrp | ifilter("len(mem)")
1335 >>> igrp | ifilter("len(mem)")
1358 >>> sys.modules | ifilter(lambda _:_.value is not None)
1336 >>> sys.modules | ifilter(lambda _:_.value is not None)
1359 """
1337 """
1360
1338
1361 def __init__(self, expr, globals=None, errors="raiseifallfail"):
1339 def __init__(self, expr, globals=None, errors="raiseifallfail"):
1362 """
1340 """
1363 Create an ``ifilter`` object. ``expr`` can be a callable or a string
1341 Create an ``ifilter`` object. ``expr`` can be a callable or a string
1364 containing an expression. ``globals`` will be used as the global
1342 containing an expression. ``globals`` will be used as the global
1365 namespace for calling string expressions (defaulting to IPython's
1343 namespace for calling string expressions (defaulting to IPython's
1366 user namespace). ``errors`` specifies how exception during evaluation
1344 user namespace). ``errors`` specifies how exception during evaluation
1367 of ``expr`` are handled:
1345 of ``expr`` are handled:
1368
1346
1369 * ``drop``: drop all items that have errors;
1347 * ``drop``: drop all items that have errors;
1370
1348
1371 * ``keep``: keep all items that have errors;
1349 * ``keep``: keep all items that have errors;
1372
1350
1373 * ``keeperror``: keep the exception of all items that have errors;
1351 * ``keeperror``: keep the exception of all items that have errors;
1374
1352
1375 * ``raise``: raise the exception;
1353 * ``raise``: raise the exception;
1376
1354
1377 * ``raiseifallfail``: raise the first exception if all items have errors;
1355 * ``raiseifallfail``: raise the first exception if all items have errors;
1378 otherwise drop those with errors (this is the default).
1356 otherwise drop those with errors (this is the default).
1379 """
1357 """
1380 self.expr = expr
1358 self.expr = expr
1381 self.globals = globals
1359 self.globals = globals
1382 self.errors = errors
1360 self.errors = errors
1383
1361
1384 def __xiter__(self, mode):
1362 def __xiter__(self, mode):
1385 if callable(self.expr):
1363 if callable(self.expr):
1386 def test(item):
1364 def test(item):
1387 return self.expr(item)
1365 return self.expr(item)
1388 else:
1366 else:
1389 g = getglobals(self.globals)
1367 g = getglobals(self.globals)
1390 def test(item):
1368 def test(item):
1391 return eval(self.expr, g, AttrNamespace(item))
1369 return eval(self.expr, g, AttrNamespace(item))
1392
1370
1393 ok = 0
1371 ok = 0
1394 exc_info = None
1372 exc_info = None
1395 for item in xiter(self.input, mode):
1373 for item in xiter(self.input, mode):
1396 try:
1374 try:
1397 if test(item):
1375 if test(item):
1398 yield item
1376 yield item
1399 ok += 1
1377 ok += 1
1400 except (KeyboardInterrupt, SystemExit):
1378 except (KeyboardInterrupt, SystemExit):
1401 raise
1379 raise
1402 except Exception, exc:
1380 except Exception, exc:
1403 if self.errors == "drop":
1381 if self.errors == "drop":
1404 pass # Ignore errors
1382 pass # Ignore errors
1405 elif self.errors == "keep":
1383 elif self.errors == "keep":
1406 yield item
1384 yield item
1407 elif self.errors == "keeperror":
1385 elif self.errors == "keeperror":
1408 yield exc
1386 yield exc
1409 elif self.errors == "raise":
1387 elif self.errors == "raise":
1410 raise
1388 raise
1411 elif self.errors == "raiseifallfail":
1389 elif self.errors == "raiseifallfail":
1412 if exc_info is None:
1390 if exc_info is None:
1413 exc_info = sys.exc_info()
1391 exc_info = sys.exc_info()
1414 if not ok and exc_info is not None:
1392 if not ok and exc_info is not None:
1415 raise exc_info[0], exc_info[1], exc_info[2]
1393 raise exc_info[0], exc_info[1], exc_info[2]
1416
1394
1417 def __xrepr__(self, mode):
1395 def __xrepr__(self, mode):
1418 yield (-1, True)
1419 if mode == "header" or mode == "footer":
1396 if mode == "header" or mode == "footer":
1420 input = getattr(self, "input", None)
1397 input = getattr(self, "input", None)
1421 if input is not None:
1398 if input is not None:
1422 for part in xrepr(input, mode):
1399 for part in xrepr(input, mode):
1423 yield part
1400 yield part
1424 yield (astyle.style_default, " | ")
1401 yield (astyle.style_default, " | ")
1425 yield (astyle.style_default, "%s(" % self.__class__.__name__)
1402 yield (astyle.style_default, "%s(" % self.__class__.__name__)
1426 for part in xrepr(self.expr, "default"):
1403 for part in xrepr(self.expr, "default"):
1427 yield part
1404 yield part
1428 yield (astyle.style_default, ")")
1405 yield (astyle.style_default, ")")
1429 else:
1406 else:
1430 yield (astyle.style_default, repr(self))
1407 yield (astyle.style_default, repr(self))
1431
1408
1432 def __repr__(self):
1409 def __repr__(self):
1433 return "<%s.%s expr=%r at 0x%x>" % \
1410 return "<%s.%s expr=%r at 0x%x>" % \
1434 (self.__class__.__module__, self.__class__.__name__,
1411 (self.__class__.__module__, self.__class__.__name__,
1435 self.expr, id(self))
1412 self.expr, id(self))
1436
1413
1437
1414
1438 class ieval(Pipe):
1415 class ieval(Pipe):
1439 """
1416 """
1440 Evaluate an expression for each object in the input pipe.
1417 Evaluate an expression for each object in the input pipe.
1441
1418
1442 Examples:
1419 Examples:
1443
1420
1444 >>> ils | ieval("_.abspath()")
1421 >>> ils | ieval("_.abspath()")
1445 >>> sys.path | ieval(ifile)
1422 >>> sys.path | ieval(ifile)
1446 """
1423 """
1447
1424
1448 def __init__(self, expr, globals=None, errors="raiseifallfail"):
1425 def __init__(self, expr, globals=None, errors="raiseifallfail"):
1449 """
1426 """
1450 Create an ``ieval`` object. ``expr`` can be a callable or a string
1427 Create an ``ieval`` object. ``expr`` can be a callable or a string
1451 containing an expression. For the meaning of ``globals`` and
1428 containing an expression. For the meaning of ``globals`` and
1452 ``errors`` see ``ifilter``.
1429 ``errors`` see ``ifilter``.
1453 """
1430 """
1454 self.expr = expr
1431 self.expr = expr
1455 self.globals = globals
1432 self.globals = globals
1456 self.errors = errors
1433 self.errors = errors
1457
1434
1458 def __xiter__(self, mode):
1435 def __xiter__(self, mode):
1459 if callable(self.expr):
1436 if callable(self.expr):
1460 def do(item):
1437 def do(item):
1461 return self.expr(item)
1438 return self.expr(item)
1462 else:
1439 else:
1463 g = getglobals(self.globals)
1440 g = getglobals(self.globals)
1464 def do(item):
1441 def do(item):
1465 return eval(self.expr, g, AttrNamespace(item))
1442 return eval(self.expr, g, AttrNamespace(item))
1466
1443
1467 ok = 0
1444 ok = 0
1468 exc_info = None
1445 exc_info = None
1469 for item in xiter(self.input, mode):
1446 for item in xiter(self.input, mode):
1470 try:
1447 try:
1471 yield do(item)
1448 yield do(item)
1472 except (KeyboardInterrupt, SystemExit):
1449 except (KeyboardInterrupt, SystemExit):
1473 raise
1450 raise
1474 except Exception, exc:
1451 except Exception, exc:
1475 if self.errors == "drop":
1452 if self.errors == "drop":
1476 pass # Ignore errors
1453 pass # Ignore errors
1477 elif self.errors == "keep":
1454 elif self.errors == "keep":
1478 yield item
1455 yield item
1479 elif self.errors == "keeperror":
1456 elif self.errors == "keeperror":
1480 yield exc
1457 yield exc
1481 elif self.errors == "raise":
1458 elif self.errors == "raise":
1482 raise
1459 raise
1483 elif self.errors == "raiseifallfail":
1460 elif self.errors == "raiseifallfail":
1484 if exc_info is None:
1461 if exc_info is None:
1485 exc_info = sys.exc_info()
1462 exc_info = sys.exc_info()
1486 if not ok and exc_info is not None:
1463 if not ok and exc_info is not None:
1487 raise exc_info[0], exc_info[1], exc_info[2]
1464 raise exc_info[0], exc_info[1], exc_info[2]
1488
1465
1489 def __xrepr__(self, mode):
1466 def __xrepr__(self, mode):
1490 yield (-1, True)
1491 if mode == "header" or mode == "footer":
1467 if mode == "header" or mode == "footer":
1492 input = getattr(self, "input", None)
1468 input = getattr(self, "input", None)
1493 if input is not None:
1469 if input is not None:
1494 for part in xrepr(input, mode):
1470 for part in xrepr(input, mode):
1495 yield part
1471 yield part
1496 yield (astyle.style_default, " | ")
1472 yield (astyle.style_default, " | ")
1497 yield (astyle.style_default, "%s(" % self.__class__.__name__)
1473 yield (astyle.style_default, "%s(" % self.__class__.__name__)
1498 for part in xrepr(self.expr, "default"):
1474 for part in xrepr(self.expr, "default"):
1499 yield part
1475 yield part
1500 yield (astyle.style_default, ")")
1476 yield (astyle.style_default, ")")
1501 else:
1477 else:
1502 yield (astyle.style_default, repr(self))
1478 yield (astyle.style_default, repr(self))
1503
1479
1504 def __repr__(self):
1480 def __repr__(self):
1505 return "<%s.%s expr=%r at 0x%x>" % \
1481 return "<%s.%s expr=%r at 0x%x>" % \
1506 (self.__class__.__module__, self.__class__.__name__,
1482 (self.__class__.__module__, self.__class__.__name__,
1507 self.expr, id(self))
1483 self.expr, id(self))
1508
1484
1509
1485
1510 class ienum(Pipe):
1486 class ienum(Pipe):
1511 """
1487 """
1512 Enumerate the input pipe (i.e. wrap each input object in an object
1488 Enumerate the input pipe (i.e. wrap each input object in an object
1513 with ``index`` and ``object`` attributes).
1489 with ``index`` and ``object`` attributes).
1514
1490
1515 Examples:
1491 Examples:
1516
1492
1517 >>> xrange(20) | ieval("_,_*_") | ienum | ifilter("index % 2 == 0") | ieval("object")
1493 >>> xrange(20) | ieval("_,_*_") | ienum | ifilter("index % 2 == 0") | ieval("object")
1518 """
1494 """
1519 def __xiter__(self, mode):
1495 def __xiter__(self, mode):
1520 fields = ("index", "object")
1496 fields = ("index", "object")
1521 for (index, object) in enumerate(xiter(self.input, mode)):
1497 for (index, object) in enumerate(xiter(self.input, mode)):
1522 yield Fields(fields, index=index, object=object)
1498 yield Fields(fields, index=index, object=object)
1523
1499
1524
1500
1525 class isort(Pipe):
1501 class isort(Pipe):
1526 """
1502 """
1527 Sorts the input pipe.
1503 Sorts the input pipe.
1528
1504
1529 Examples:
1505 Examples:
1530
1506
1531 >>> ils | isort("size")
1507 >>> ils | isort("size")
1532 >>> ils | isort("_.isdir(), _.lower()", reverse=True)
1508 >>> ils | isort("_.isdir(), _.lower()", reverse=True)
1533 """
1509 """
1534
1510
1535 def __init__(self, key, globals=None, reverse=False):
1511 def __init__(self, key, globals=None, reverse=False):
1536 """
1512 """
1537 Create an ``isort`` object. ``key`` can be a callable or a string
1513 Create an ``isort`` object. ``key`` can be a callable or a string
1538 containing an expression. If ``reverse`` is true the sort order will
1514 containing an expression. If ``reverse`` is true the sort order will
1539 be reversed. For the meaning of ``globals`` see ``ifilter``.
1515 be reversed. For the meaning of ``globals`` see ``ifilter``.
1540 """
1516 """
1541 self.key = key
1517 self.key = key
1542 self.globals = globals
1518 self.globals = globals
1543 self.reverse = reverse
1519 self.reverse = reverse
1544
1520
1545 def __xiter__(self, mode):
1521 def __xiter__(self, mode):
1546 if callable(self.key):
1522 if callable(self.key):
1547 items = sorted(
1523 items = sorted(
1548 xiter(self.input, mode),
1524 xiter(self.input, mode),
1549 key=self.key,
1525 key=self.key,
1550 reverse=self.reverse
1526 reverse=self.reverse
1551 )
1527 )
1552 else:
1528 else:
1553 g = getglobals(self.globals)
1529 g = getglobals(self.globals)
1554 def key(item):
1530 def key(item):
1555 return eval(self.key, g, AttrNamespace(item))
1531 return eval(self.key, g, AttrNamespace(item))
1556 items = sorted(
1532 items = sorted(
1557 xiter(self.input, mode),
1533 xiter(self.input, mode),
1558 key=key,
1534 key=key,
1559 reverse=self.reverse
1535 reverse=self.reverse
1560 )
1536 )
1561 for item in items:
1537 for item in items:
1562 yield item
1538 yield item
1563
1539
1564 def __xrepr__(self, mode):
1540 def __xrepr__(self, mode):
1565 yield (-1, True)
1566 if mode == "header" or mode == "footer":
1541 if mode == "header" or mode == "footer":
1567 input = getattr(self, "input", None)
1542 input = getattr(self, "input", None)
1568 if input is not None:
1543 if input is not None:
1569 for part in xrepr(input, mode):
1544 for part in xrepr(input, mode):
1570 yield part
1545 yield part
1571 yield (astyle.style_default, " | ")
1546 yield (astyle.style_default, " | ")
1572 yield (astyle.style_default, "%s(" % self.__class__.__name__)
1547 yield (astyle.style_default, "%s(" % self.__class__.__name__)
1573 for part in xrepr(self.key, "default"):
1548 for part in xrepr(self.key, "default"):
1574 yield part
1549 yield part
1575 if self.reverse:
1550 if self.reverse:
1576 yield (astyle.style_default, ", ")
1551 yield (astyle.style_default, ", ")
1577 for part in xrepr(True, "default"):
1552 for part in xrepr(True, "default"):
1578 yield part
1553 yield part
1579 yield (astyle.style_default, ")")
1554 yield (astyle.style_default, ")")
1580 else:
1555 else:
1581 yield (astyle.style_default, repr(self))
1556 yield (astyle.style_default, repr(self))
1582
1557
1583 def __repr__(self):
1558 def __repr__(self):
1584 return "<%s.%s key=%r reverse=%r at 0x%x>" % \
1559 return "<%s.%s key=%r reverse=%r at 0x%x>" % \
1585 (self.__class__.__module__, self.__class__.__name__,
1560 (self.__class__.__module__, self.__class__.__name__,
1586 self.key, self.reverse, id(self))
1561 self.key, self.reverse, id(self))
1587
1562
1588
1563
1589 tab = 3 # for expandtabs()
1564 tab = 3 # for expandtabs()
1590
1565
1591 def _format(field):
1566 def _format(field):
1592 if isinstance(field, str):
1567 if isinstance(field, str):
1593 text = repr(field.expandtabs(tab))[1:-1]
1568 text = repr(field.expandtabs(tab))[1:-1]
1594 elif isinstance(field, unicode):
1569 elif isinstance(field, unicode):
1595 text = repr(field.expandtabs(tab))[2:-1]
1570 text = repr(field.expandtabs(tab))[2:-1]
1596 elif isinstance(field, datetime.datetime):
1571 elif isinstance(field, datetime.datetime):
1597 # Don't use strftime() here, as this requires year >= 1900
1572 # Don't use strftime() here, as this requires year >= 1900
1598 text = "%04d-%02d-%02d %02d:%02d:%02d.%06d" % \
1573 text = "%04d-%02d-%02d %02d:%02d:%02d.%06d" % \
1599 (field.year, field.month, field.day,
1574 (field.year, field.month, field.day,
1600 field.hour, field.minute, field.second, field.microsecond)
1575 field.hour, field.minute, field.second, field.microsecond)
1601 elif isinstance(field, datetime.date):
1576 elif isinstance(field, datetime.date):
1602 text = "%04d-%02d-%02d" % (field.year, field.month, field.day)
1577 text = "%04d-%02d-%02d" % (field.year, field.month, field.day)
1603 else:
1578 else:
1604 text = repr(field)
1579 text = repr(field)
1605 return text
1580 return text
1606
1581
1607
1582
1608 class Display(object):
1583 class Display(object):
1609 class __metaclass__(type):
1584 class __metaclass__(type):
1610 def __ror__(self, input):
1585 def __ror__(self, input):
1611 return input | self()
1586 return input | self()
1612
1587
1613 def __ror__(self, input):
1588 def __ror__(self, input):
1614 self.input = input
1589 self.input = input
1615 return self
1590 return self
1616
1591
1617 def display(self):
1592 def display(self):
1618 pass
1593 pass
1619
1594
1620
1595
1621 class iless(Display):
1596 class iless(Display):
1622 cmd = "less --quit-if-one-screen --LONG-PROMPT --LINE-NUMBERS --chop-long-lines --shift=8 --RAW-CONTROL-CHARS"
1597 cmd = "less --quit-if-one-screen --LONG-PROMPT --LINE-NUMBERS --chop-long-lines --shift=8 --RAW-CONTROL-CHARS"
1623
1598
1624 def display(self):
1599 def display(self):
1625 try:
1600 try:
1626 pager = os.popen(self.cmd, "w")
1601 pager = os.popen(self.cmd, "w")
1627 try:
1602 try:
1628 for item in xiter(self.input, "default"):
1603 for item in xiter(self.input, "default"):
1629 attrs = xattrs(item, "default")
1604 attrs = xattrs(item, "default")
1630 attrs = ["%s=%s" % (a, _format(_getattr(item, a))) for a in attrs]
1605 attrs = ["%s=%s" % (a, _format(_getattr(item, a))) for a in attrs]
1631 pager.write(" ".join(attrs))
1606 pager.write(" ".join(attrs))
1632 pager.write("\n")
1607 pager.write("\n")
1633 finally:
1608 finally:
1634 pager.close()
1609 pager.close()
1635 except Exception, exc:
1610 except Exception, exc:
1636 print "%s: %s" % (exc.__class__.__name__, str(exc))
1611 print "%s: %s" % (exc.__class__.__name__, str(exc))
1637
1612
1638
1613
1639 def xformat(value, mode, maxlength):
1614 def xformat(value, mode, maxlength):
1640 align = None
1615 align = None
1641 full = False
1616 full = True
1642 width = 0
1617 width = 0
1643 text = astyle.Text()
1618 text = astyle.Text()
1644 for part in xrepr(value, mode):
1619 for part in xrepr(value, mode):
1645 # part is (alignment, stop)
1620 # part is (alignment, stop)
1646 if isinstance(part[0], int):
1621 if isinstance(part[0], int):
1647 # only consider the first occurence
1622 # only consider the first occurence
1648 if align is None:
1623 if align is None:
1649 align = part[0]
1624 align = part[0]
1650 full = part[1]
1625 full = part[1]
1651 # part is (style, text)
1626 # part is (style, text)
1652 else:
1627 else:
1653 text.append(part)
1628 text.append(part)
1654 width += len(part[1])
1629 width += len(part[1])
1655 if width >= maxlength and not full:
1630 if width >= maxlength and not full:
1656 text.append((astyle.style_ellisis, "..."))
1631 text.append((astyle.style_ellisis, "..."))
1657 width += 3
1632 width += 3
1658 break
1633 break
1659 if align is None: # default to left alignment
1634 if align is None: # default to left alignment
1660 align = -1
1635 align = -1
1661 return (align, width, text)
1636 return (align, width, text)
1662
1637
1663
1638
1664 class idump(Display):
1639 class idump(Display):
1665 # The approximate maximum length of a column entry
1640 # The approximate maximum length of a column entry
1666 maxattrlength = 200
1641 maxattrlength = 200
1667
1642
1668 # Style for column names
1643 # Style for column names
1669 style_header = astyle.Style.fromstr("white:black:bold")
1644 style_header = astyle.Style.fromstr("white:black:bold")
1670
1645
1671 def __init__(self, *attrs):
1646 def __init__(self, *attrs):
1672 self.attrs = attrs
1647 self.attrs = attrs
1673 self.headerpadchar = " "
1648 self.headerpadchar = " "
1674 self.headersepchar = "|"
1649 self.headersepchar = "|"
1675 self.datapadchar = " "
1650 self.datapadchar = " "
1676 self.datasepchar = "|"
1651 self.datasepchar = "|"
1677
1652
1678 def display(self):
1653 def display(self):
1679 stream = genutils.Term.cout
1654 stream = genutils.Term.cout
1680 allattrs = []
1655 allattrs = []
1681 allattrset = set()
1656 allattrset = set()
1682 colwidths = {}
1657 colwidths = {}
1683 rows = []
1658 rows = []
1684 for item in xiter(self.input, "default"):
1659 for item in xiter(self.input, "default"):
1685 row = {}
1660 row = {}
1686 attrs = self.attrs
1661 attrs = self.attrs
1687 if not attrs:
1662 if not attrs:
1688 attrs = xattrs(item, "default")
1663 attrs = xattrs(item, "default")
1689 for attrname in attrs:
1664 for attrname in attrs:
1690 if attrname not in allattrset:
1665 if attrname not in allattrset:
1691 allattrs.append(attrname)
1666 allattrs.append(attrname)
1692 allattrset.add(attrname)
1667 allattrset.add(attrname)
1693 colwidths[attrname] = len(_attrname(attrname))
1668 colwidths[attrname] = len(_attrname(attrname))
1694 try:
1669 try:
1695 value = _getattr(item, attrname, None)
1670 value = _getattr(item, attrname, None)
1696 except (KeyboardInterrupt, SystemExit):
1671 except (KeyboardInterrupt, SystemExit):
1697 raise
1672 raise
1698 except Exception, exc:
1673 except Exception, exc:
1699 value = exc
1674 value = exc
1700 (align, width, text) = xformat(value, "cell", self.maxattrlength)
1675 (align, width, text) = xformat(value, "cell", self.maxattrlength)
1701 colwidths[attrname] = max(colwidths[attrname], width)
1676 colwidths[attrname] = max(colwidths[attrname], width)
1702 # remember alignment, length and colored parts
1677 # remember alignment, length and colored parts
1703 row[attrname] = (align, width, text)
1678 row[attrname] = (align, width, text)
1704 rows.append(row)
1679 rows.append(row)
1705
1680
1706 stream.write("\n")
1681 stream.write("\n")
1707 for (i, attrname) in enumerate(allattrs):
1682 for (i, attrname) in enumerate(allattrs):
1708 self.style_header(_attrname(attrname)).write(stream)
1683 self.style_header(_attrname(attrname)).write(stream)
1709 spc = colwidths[attrname] - len(_attrname(attrname))
1684 spc = colwidths[attrname] - len(_attrname(attrname))
1710 if i < len(colwidths)-1:
1685 if i < len(colwidths)-1:
1711 stream.write(self.headerpadchar*spc)
1686 stream.write(self.headerpadchar*spc)
1712 stream.write(self.headersepchar)
1687 stream.write(self.headersepchar)
1713 stream.write("\n")
1688 stream.write("\n")
1714
1689
1715 for row in rows:
1690 for row in rows:
1716 for (i, attrname) in enumerate(allattrs):
1691 for (i, attrname) in enumerate(allattrs):
1717 (align, width, text) = row[attrname]
1692 (align, width, text) = row[attrname]
1718 spc = colwidths[attrname] - width
1693 spc = colwidths[attrname] - width
1719 if align == -1:
1694 if align == -1:
1720 text.write(stream)
1695 text.write(stream)
1721 if i < len(colwidths)-1:
1696 if i < len(colwidths)-1:
1722 stream.write(self.datapadchar*spc)
1697 stream.write(self.datapadchar*spc)
1723 elif align == 0:
1698 elif align == 0:
1724 spc = colwidths[attrname] - width
1699 spc = colwidths[attrname] - width
1725 spc1 = spc//2
1700 spc1 = spc//2
1726 spc2 = spc-spc1
1701 spc2 = spc-spc1
1727 stream.write(self.datapadchar*spc1)
1702 stream.write(self.datapadchar*spc1)
1728 text.write(stream)
1703 text.write(stream)
1729 if i < len(colwidths)-1:
1704 if i < len(colwidths)-1:
1730 stream.write(self.datapadchar*spc2)
1705 stream.write(self.datapadchar*spc2)
1731 else:
1706 else:
1732 stream.write(self.datapadchar*spc)
1707 stream.write(self.datapadchar*spc)
1733 text.write(stream)
1708 text.write(stream)
1734 if i < len(colwidths)-1:
1709 if i < len(colwidths)-1:
1735 stream.write(self.datasepchar)
1710 stream.write(self.datasepchar)
1736 stream.write("\n")
1711 stream.write("\n")
1737
1712
1738
1713
1739 class XMode(object):
1714 class XMode(object):
1740 """
1715 """
1741 An ``XMode`` object describes one enter mode available for an object
1716 An ``XMode`` object describes one enter mode available for an object
1742 """
1717 """
1743 def __init__(self, object, mode, title=None, description=None):
1718 def __init__(self, object, mode, title=None, description=None):
1744 """
1719 """
1745 Create a new ``XMode`` object for the object ``object``. This object
1720 Create a new ``XMode`` object for the object ``object``. This object
1746 must support the enter mode ``mode`` (i.e. ``object.__xiter__(mode)``
1721 must support the enter mode ``mode`` (i.e. ``object.__xiter__(mode)``
1747 must return an iterable). ``title`` and ``description`` will be
1722 must return an iterable). ``title`` and ``description`` will be
1748 displayed in the browser when selecting among the available modes.
1723 displayed in the browser when selecting among the available modes.
1749 """
1724 """
1750 self.object = object
1725 self.object = object
1751 self.mode = mode
1726 self.mode = mode
1752 self.title = title
1727 self.title = title
1753 self.description = description
1728 self.description = description
1754
1729
1755 def __repr__(self):
1730 def __repr__(self):
1756 return "<%s.%s object mode=%r at 0x%x>" % \
1731 return "<%s.%s object mode=%r at 0x%x>" % \
1757 (self.__class__.__module__, self.__class__.__name__,
1732 (self.__class__.__module__, self.__class__.__name__,
1758 self.mode, id(self))
1733 self.mode, id(self))
1759
1734
1760 def __xrepr__(self, mode):
1735 def __xrepr__(self, mode):
1761 yield (-1, True)
1762 if mode == "header" or mode == "footer":
1736 if mode == "header" or mode == "footer":
1763 yield (astyle.style_default, self.title)
1737 yield (astyle.style_default, self.title)
1764 else:
1738 else:
1765 yield (astyle.style_default, repr(self))
1739 yield (astyle.style_default, repr(self))
1766
1740
1767 def __xattrs__(self, mode):
1741 def __xattrs__(self, mode):
1768 if mode == "detail":
1742 if mode == "detail":
1769 return ("object", "mode", "title", "description")
1743 return ("object", "mode", "title", "description")
1770 return ("title", "description")
1744 return ("title", "description")
1771
1745
1772 def __xiter__(self, mode):
1746 def __xiter__(self, mode):
1773 return xiter(self.object, self.mode)
1747 return xiter(self.object, self.mode)
1774
1748
1775
1749
1776 class XAttr(object):
1750 class XAttr(object):
1777 def __init__(self, object, name):
1751 def __init__(self, object, name):
1778 self.name = _attrname(name)
1752 self.name = _attrname(name)
1779
1753
1780 try:
1754 try:
1781 self.value = _getattr(object, name)
1755 self.value = _getattr(object, name)
1782 except (KeyboardInterrupt, SystemExit):
1756 except (KeyboardInterrupt, SystemExit):
1783 raise
1757 raise
1784 except Exception, exc:
1758 except Exception, exc:
1785 if exc.__class__.__module__ == "exceptions":
1759 if exc.__class__.__module__ == "exceptions":
1786 self.value = exc.__class__.__name__
1760 self.value = exc.__class__.__name__
1787 else:
1761 else:
1788 self.value = "%s.%s" % \
1762 self.value = "%s.%s" % \
1789 (exc.__class__.__module__, exc.__class__.__name__)
1763 (exc.__class__.__module__, exc.__class__.__name__)
1790 self.type = self.value
1764 self.type = self.value
1791 else:
1765 else:
1792 t = type(self.value)
1766 t = type(self.value)
1793 if t.__module__ == "__builtin__":
1767 if t.__module__ == "__builtin__":
1794 self.type = t.__name__
1768 self.type = t.__name__
1795 else:
1769 else:
1796 self.type = "%s.%s" % (t.__module__, t.__name__)
1770 self.type = "%s.%s" % (t.__module__, t.__name__)
1797
1771
1798 doc = None
1772 doc = None
1799 if isinstance(name, basestring):
1773 if isinstance(name, basestring):
1800 if name.endswith("()"):
1774 if name.endswith("()"):
1801 doc = getattr(getattr(object, name[:-2]), "__doc__", None)
1775 doc = getattr(getattr(object, name[:-2]), "__doc__", None)
1802 else:
1776 else:
1803 try:
1777 try:
1804 meta = getattr(type(object), name)
1778 meta = getattr(type(object), name)
1805 except AttributeError:
1779 except AttributeError:
1806 pass
1780 pass
1807 else:
1781 else:
1808 if isinstance(meta, property):
1782 if isinstance(meta, property):
1809 doc = getattr(meta, "__doc__", None)
1783 doc = getattr(meta, "__doc__", None)
1810 elif callable(name):
1784 elif callable(name):
1811 doc = getattr(name, "__doc__", None)
1785 doc = getattr(name, "__doc__", None)
1812 if isinstance(doc, basestring):
1786 if isinstance(doc, basestring):
1813 doc = doc.strip()
1787 doc = doc.strip()
1814 self.doc = doc
1788 self.doc = doc
1815
1789
1816 def __xattrs__(self, mode):
1790 def __xattrs__(self, mode):
1817 return ("name", "type", "doc", "value")
1791 return ("name", "type", "doc", "value")
1818
1792
1819
1793
1820 try:
1794 try:
1821 from ibrowse import ibrowse
1795 from ibrowse import ibrowse
1822 except ImportError:
1796 except ImportError:
1823 # No curses (probably Windows) => use ``idump`` as the default display.
1797 # No curses (probably Windows) => use ``idump`` as the default display.
1824 defaultdisplay = idump
1798 defaultdisplay = idump
1825 else:
1799 else:
1826 defaultdisplay = ibrowse
1800 defaultdisplay = ibrowse
1827 __all__.append("ibrowse")
1801 __all__.append("ibrowse")
1828
1802
1829
1803
1830 # If we're running under IPython, install an IPython displayhook that
1804 # If we're running under IPython, install an IPython displayhook that
1831 # returns the object from Display.display(), else install a displayhook
1805 # returns the object from Display.display(), else install a displayhook
1832 # directly as sys.displayhook
1806 # directly as sys.displayhook
1833 api = None
1807 api = None
1834 if ipapi is not None:
1808 if ipapi is not None:
1835 try:
1809 try:
1836 api = ipapi.get()
1810 api = ipapi.get()
1837 except AttributeError:
1811 except AttributeError:
1838 pass
1812 pass
1839
1813
1840 if api is not None:
1814 if api is not None:
1841 def displayhook(self, obj):
1815 def displayhook(self, obj):
1842 if isinstance(obj, type) and issubclass(obj, Table):
1816 if isinstance(obj, type) and issubclass(obj, Table):
1843 obj = obj()
1817 obj = obj()
1844 if isinstance(obj, Table):
1818 if isinstance(obj, Table):
1845 obj = obj | defaultdisplay
1819 obj = obj | defaultdisplay
1846 if isinstance(obj, Display):
1820 if isinstance(obj, Display):
1847 return obj.display()
1821 return obj.display()
1848 else:
1822 else:
1849 raise ipapi.TryNext
1823 raise ipapi.TryNext
1850 api.set_hook("result_display", displayhook)
1824 api.set_hook("result_display", displayhook)
1851 else:
1825 else:
1852 def installdisplayhook():
1826 def installdisplayhook():
1853 _originalhook = sys.displayhook
1827 _originalhook = sys.displayhook
1854 def displayhook(obj):
1828 def displayhook(obj):
1855 if isinstance(obj, type) and issubclass(obj, Table):
1829 if isinstance(obj, type) and issubclass(obj, Table):
1856 obj = obj()
1830 obj = obj()
1857 if isinstance(obj, Table):
1831 if isinstance(obj, Table):
1858 obj = obj | defaultdisplay
1832 obj = obj | defaultdisplay
1859 if isinstance(obj, Display):
1833 if isinstance(obj, Display):
1860 return obj.display()
1834 return obj.display()
1861 else:
1835 else:
1862 _originalhook(obj)
1836 _originalhook(obj)
1863 sys.displayhook = displayhook
1837 sys.displayhook = displayhook
1864 installdisplayhook()
1838 installdisplayhook()
General Comments 0
You need to be logged in to leave comments. Login now