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