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