1
# -*- coding: iso-8859-1 -*-
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
6
objects imported this way starts with ``i`` to minimize collisions.
8
``ipipe`` supports "pipeline expressions", which is something resembling Unix
11
>>> ienv | isort("key.lower()")
13
This gives a listing of all environment variables sorted by name.
16
There are three types of objects in a pipeline expression:
18
* ``Table``s: These objects produce items. Examples are ``ils`` (listing the
19
current directory, ``ienv`` (listing environment variables), ``ipwd`` (listing
20
user accounts) and ``igrp`` (listing user groups). A ``Table`` must be the
21
first object in a pipe expression.
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:
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
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
31
expression. If a pipeline expression doesn't end in a display object a default
32
display objects will be used. One example is ``ibrowse`` which is a ``curses``
36
Adding support for pipeline expressions to your own objects can be done through
37
three extensions points (all of them optional):
39
* An object that will be displayed as a row by a ``Display`` object should
40
implement the method ``__xattrs__(self, mode)`` method or register an
41
implementation of the generic function ``xattrs``. For more info see ``xattrs``.
43
* When an object ``foo`` is displayed by a ``Display`` object, the generic
44
function ``xrepr`` is used.
46
* Objects that can be iterated by ``Pipe``s must iterable. For special cases,
47
where iteration for display is different than the normal iteration a special
48
implementation can be registered with the generic function ``xiter``. This
49
makes it possible to use dictionaries and modules in pipeline expressions,
53
>>> sys | ifilter("isinstance(value, int)") | idump
60
>>> sys.modules | ifilter("_.value is not None") | isort("_.key.lower()")
63
Note: The expression strings passed to ``ifilter()`` and ``isort()`` can
64
refer to the object to be filtered or sorted via the variable ``_`` and to any
65
of the attributes of the object, i.e.::
67
>>> sys.modules | ifilter("_.value is not None") | isort("_.key.lower()")
71
>>> sys.modules | ifilter("value is not None") | isort("key.lower()")
73
In addition to expression strings, it's possible to pass callables (taking
74
the object as an argument) to ``ifilter()``, ``isort()`` and ``ieval()``::
76
>>> sys | ifilter(lambda _:isinstance(_.value, int)) \
77
... | ieval(lambda _: (_.key, hex(_.value))) | idump
86
import sys, os, os.path, stat, glob, new, csv, datetime, types
87
import itertools, mimetypes, StringIO
89
try: # Python 2.3 compatibility
94
deque = collections.deque
96
try: # Python 2.3 compatibility
102
try: # Python 2.3 compatibility
105
def sorted(iterator, key=None, reverse=False):
106
items = list(iterator)
108
items.sort(lambda i1, i2: cmp(key(i1), key(i2)))
125
from IPython.external import simplegeneric
130
from IPython import genutils, generics
135
from IPython import ipapi
139
"ifile", "ils", "iglob", "iwalk", "ipwdentry", "ipwd", "igrpentry", "igrp",
140
"icsv", "ix", "ichain", "isort", "ifilter", "ieval", "ienum",
141
"ienv", "ihist", "ialias", "icap", "idump", "iless"
145
os.stat_float_times(True) # enable microseconds
148
class AttrNamespace(object):
150
Helper class that is used for providing a namespace for evaluating
151
expressions containing attribute names of an object.
153
def __init__(self, wrapped):
154
self.wrapped = wrapped
156
def __getitem__(self, name):
160
return getattr(self.wrapped, name)
161
except AttributeError:
164
# Python 2.3 compatibility
165
# use eval workaround to find out which names are used in the
166
# eval string and put them into the locals. This works for most
167
# normal uses case, bizarre ones like accessing the locals()
170
eval("_", None, AttrNamespace(None))
173
def eval(codestring, _globals, _locals):
175
eval(source[, globals[, locals]]) -> value
177
Evaluate the source in the context of globals and locals.
178
The source may be a string representing a Python expression
179
or a code object as returned by compile().
180
The globals must be a dictionary and locals can be any mappping.
182
This function is a workaround for the shortcomings of
186
if isinstance(codestring, basestring):
187
code = compile(codestring, "_eval", "eval")
191
for name in code.co_names:
193
newlocals[name] = _locals[name]
196
return real_eval(code, _globals, newlocals)
202
def item(iterator, index, default=noitem):
204
Return the ``index``th item from the iterator ``iterator``.
205
``index`` must be an integer (negative integers are relative to the
206
end (i.e. the last items produced by the iterator)).
208
If ``default`` is given, this will be the default value when
209
the iterator doesn't contain an item at this position. Otherwise an
210
``IndexError`` will be raised.
212
Note that using this function will partially or totally exhaust the
217
for item in iterator:
224
for item in iterator:
229
return cache.popleft()
230
if default is noitem:
231
raise IndexError(index)
238
Return the global namespace that is used for expression strings in
239
``ifilter`` and others. This is ``g`` or (if ``g`` is ``None``) IPython's
243
if ipapi is not None:
251
class Descriptor(object):
253
A ``Descriptor`` object is used for describing the attributes of objects.
256
return hash(self.__class__) ^ hash(self.key())
258
def __eq__(self, other):
259
return self.__class__ is other.__class__ and self.key() == other.key()
261
def __ne__(self, other):
262
return self.__class__ is not other.__class__ or self.key() != other.key()
269
Return the name of this attribute for display by a ``Display`` object
270
(e.g. as a column title).
277
def attrtype(self, obj):
279
Return the type of this attribute (i.e. something like "attribute" or
283
def valuetype(self, obj):
285
Return the type of this attribute value of the object ``obj``.
288
def value(self, obj):
290
Return the value of this attribute of the object ``obj``.
295
Return the documentation for this attribute.
298
def shortdoc(self, obj):
300
Return a short documentation for this attribute (defaulting to the
305
doc = doc.strip().splitlines()[0].strip()
310
Return an iterator for this attribute of the object ``obj``.
312
return xiter(self.value(obj))
315
class SelfDescriptor(Descriptor):
317
A ``SelfDescriptor`` describes the object itself.
322
def attrtype(self, obj):
325
def valuetype(self, obj):
328
def value(self, obj):
334
selfdescriptor = SelfDescriptor() # there's no need for more than one
337
class AttributeDescriptor(Descriptor):
339
An ``AttributeDescriptor`` describes a simple attribute of an object.
341
__slots__ = ("_name", "_doc")
343
def __init__(self, name, doc=None):
353
def attrtype(self, obj):
356
def valuetype(self, obj):
357
return type(getattr(obj, self._name))
359
def value(self, obj):
360
return getattr(obj, self._name)
363
if self._doc is None:
364
return "Attribute(%r)" % self._name
366
return "Attribute(%r, %r)" % (self._name, self._doc)
369
class IndexDescriptor(Descriptor):
371
An ``IndexDescriptor`` describes an "attribute" of an object that is fetched
374
__slots__ = ("_index",)
376
def __init__(self, index):
382
def attrtype(self, obj):
385
def valuetype(self, obj):
386
return type(obj[self._index])
388
def value(self, obj):
389
return obj[self._index]
392
return "Index(%r)" % self._index
395
class MethodDescriptor(Descriptor):
397
A ``MethodDescriptor`` describes a method of an object that can be called
398
without argument. Note that this method shouldn't change the object.
400
__slots__ = ("_name", "_doc")
402
def __init__(self, name, doc=None):
410
if self._doc is None:
411
return getattr(obj, self._name).__doc__
414
def attrtype(self, obj):
417
def valuetype(self, obj):
418
return type(self.value(obj))
420
def value(self, obj):
421
return getattr(obj, self._name)()
424
if self._doc is None:
425
return "Method(%r)" % self._name
427
return "Method(%r, %r)" % (self._name, self._doc)
430
class IterAttributeDescriptor(Descriptor):
432
An ``IterAttributeDescriptor`` works like an ``AttributeDescriptor`` but
433
doesn't return an attribute values (because this value might be e.g. a large
436
__slots__ = ("_name", "_doc")
438
def __init__(self, name, doc=None):
448
def attrtype(self, obj):
451
def valuetype(self, obj):
454
def value(self, obj):
458
return xiter(getattr(obj, self._name))
461
if self._doc is None:
462
return "IterAttribute(%r)" % self._name
464
return "IterAttribute(%r, %r)" % (self._name, self._doc)
467
class IterMethodDescriptor(Descriptor):
469
An ``IterMethodDescriptor`` works like an ``MethodDescriptor`` but doesn't
470
return an attribute values (because this value might be e.g. a large list).
472
__slots__ = ("_name", "_doc")
474
def __init__(self, name, doc=None):
482
if self._doc is None:
483
return getattr(obj, self._name).__doc__
486
def attrtype(self, obj):
489
def valuetype(self, obj):
492
def value(self, obj):
496
return xiter(getattr(obj, self._name)())
499
if self._doc is None:
500
return "IterMethod(%r)" % self._name
502
return "IterMethod(%r, %r)" % (self._name, self._doc)
505
class FunctionDescriptor(Descriptor):
507
A ``FunctionDescriptor`` turns a function into a descriptor. The function
508
will be called with the object to get the type and value of the attribute.
510
__slots__ = ("_function", "_name", "_doc")
512
def __init__(self, function, name=None, doc=None):
513
self._function = function
518
return self._function
521
if self._name is not None:
523
return getattr(self._function, "__xname__", self._function.__name__)
526
if self._doc is None:
527
return self._function.__doc__
530
def attrtype(self, obj):
533
def valuetype(self, obj):
534
return type(self._function(obj))
536
def value(self, obj):
537
return self._function(obj)
540
if self._doc is None:
541
return "Function(%r)" % self._name
543
return "Function(%r, %r)" % (self._name, self._doc)
548
A ``Table`` is an object that produces items (just like a normal Python
549
iterator/generator does) and can be used as the first object in a pipeline
550
expression. The displayhook will open the default browser for such an object
551
(instead of simply printing the ``repr()`` result).
554
# We want to support ``foo`` and ``foo()`` in pipeline expression:
555
# So we implement the required operators (``|`` and ``+``) in the metaclass,
556
# instantiate the class and forward the operator to the instance
557
class __metaclass__(type):
561
def __or__(self, other):
562
return self() | other
564
def __add__(self, other):
565
return self() + other
567
def __radd__(self, other):
568
return other + self()
570
def __getitem__(self, index):
573
def __getitem__(self, index):
574
return item(self, index)
576
def __contains__(self, item):
577
for haveitem in self:
582
def __or__(self, other):
583
# autoinstantiate right hand side
584
if isinstance(other, type) and issubclass(other, (Table, Display)):
586
# treat simple strings and functions as ``ieval`` instances
587
elif not isinstance(other, Display) and not isinstance(other, Table):
589
# forward operations to the right hand side
590
return other.__ror__(self)
592
def __add__(self, other):
593
# autoinstantiate right hand side
594
if isinstance(other, type) and issubclass(other, Table):
596
return ichain(self, other)
598
def __radd__(self, other):
599
# autoinstantiate left hand side
600
if isinstance(other, type) and issubclass(other, Table):
602
return ichain(other, self)
607
A ``Pipe`` is an object that can be used in a pipeline expression. It
608
processes the objects it gets from its input ``Table``/``Pipe``. Note that
609
a ``Pipe`` object can't be used as the first object in a pipeline
610
expression, as it doesn't produces items itself.
612
class __metaclass__(Table.__metaclass__):
613
def __ror__(self, input):
614
return input | self()
616
def __ror__(self, input):
617
# autoinstantiate left hand side
618
if isinstance(input, type) and issubclass(input, Table):
624
def xrepr(item, mode="default"):
626
Generic function that adds color output and different display modes to ``repr``.
628
The result of an ``xrepr`` call is iterable and consists of ``(style, string)``
629
tuples. The ``style`` in this tuple must be a ``Style`` object from the
630
``astring`` module. To reconfigure the output the first yielded tuple can be
631
a ``(aligment, full)`` tuple instead of a ``(style, string)`` tuple.
632
``alignment`` can be -1 for left aligned, 0 for centered and 1 for right
633
aligned (the default is left alignment). ``full`` is a boolean that specifies
634
whether the complete output must be displayed or the ``Display`` object is
635
allowed to stop output after enough text has been produced (e.g. a syntax
636
highlighted text line would use ``True``, but for a large data structure
637
(i.e. a nested list, tuple or dictionary) ``False`` would be used).
638
The default is full output.
640
There are four different possible values for ``mode`` depending on where
641
the ``Display`` object will display ``item``:
644
``item`` will be displayed in a header line (this is used by ``ibrowse``).
647
``item`` will be displayed in a footer line (this is used by ``ibrowse``).
650
``item`` will be displayed in a table cell/list.
653
default mode. If an ``xrepr`` implementation recursively outputs objects,
654
``"default"`` must be passed in the recursive calls to ``xrepr``.
656
If no implementation is registered for ``item``, ``xrepr`` will try the
657
``__xrepr__`` method on ``item``. If ``item`` doesn't have an ``__xrepr__``
658
method it falls back to ``repr``/``__repr__`` for all modes.
661
func = item.__xrepr__
662
except AttributeError:
663
yield (astyle.style_default, repr(item))
668
except (KeyboardInterrupt, SystemExit):
671
yield (astyle.style_default, repr(item))
672
xrepr = simplegeneric.generic(xrepr)
675
def xrepr_none(self, mode="default"):
676
yield (astyle.style_type_none, repr(self))
677
xrepr.when_object(None)(xrepr_none)
680
def xrepr_noitem(self, mode="default"):
682
yield (astyle.style_nodata, "<?>")
683
xrepr.when_object(noitem)(xrepr_noitem)
686
def xrepr_bool(self, mode="default"):
687
yield (astyle.style_type_bool, repr(self))
688
xrepr.when_type(bool)(xrepr_bool)
691
def xrepr_str(self, mode="default"):
693
yield (astyle.style_default, repr(self.expandtabs(tab))[1:-1])
695
yield (astyle.style_default, repr(self))
696
xrepr.when_type(str)(xrepr_str)
699
def xrepr_unicode(self, mode="default"):
701
yield (astyle.style_default, repr(self.expandtabs(tab))[2:-1])
703
yield (astyle.style_default, repr(self))
704
xrepr.when_type(unicode)(xrepr_unicode)
707
def xrepr_number(self, mode="default"):
709
yield (astyle.style_type_number, repr(self))
710
xrepr.when_type(int)(xrepr_number)
711
xrepr.when_type(long)(xrepr_number)
712
xrepr.when_type(float)(xrepr_number)
715
def xrepr_complex(self, mode="default"):
716
yield (astyle.style_type_number, repr(self))
717
xrepr.when_type(complex)(xrepr_number)
720
def xrepr_datetime(self, mode="default"):
722
# Don't use strftime() here, as this requires year >= 1900
723
yield (astyle.style_type_datetime,
724
"%04d-%02d-%02d %02d:%02d:%02d.%06d" % \
725
(self.year, self.month, self.day,
726
self.hour, self.minute, self.second,
730
yield (astyle.style_type_datetime, repr(self))
731
xrepr.when_type(datetime.datetime)(xrepr_datetime)
734
def xrepr_date(self, mode="default"):
736
yield (astyle.style_type_datetime,
737
"%04d-%02d-%02d" % (self.year, self.month, self.day))
739
yield (astyle.style_type_datetime, repr(self))
740
xrepr.when_type(datetime.date)(xrepr_date)
743
def xrepr_time(self, mode="default"):
745
yield (astyle.style_type_datetime,
746
"%02d:%02d:%02d.%06d" % \
747
(self.hour, self.minute, self.second, self.microsecond))
749
yield (astyle.style_type_datetime, repr(self))
750
xrepr.when_type(datetime.time)(xrepr_time)
753
def xrepr_timedelta(self, mode="default"):
754
yield (astyle.style_type_datetime, repr(self))
755
xrepr.when_type(datetime.timedelta)(xrepr_timedelta)
758
def xrepr_type(self, mode="default"):
759
if self.__module__ == "__builtin__":
760
yield (astyle.style_type_type, self.__name__)
762
yield (astyle.style_type_type, "%s.%s" % (self.__module__, self.__name__))
763
xrepr.when_type(type)(xrepr_type)
766
def xrepr_exception(self, mode="default"):
767
if self.__class__.__module__ == "exceptions":
768
classname = self.__class__.__name__
770
classname = "%s.%s" % \
771
(self.__class__.__module__, self.__class__.__name__)
772
if mode == "header" or mode == "footer":
773
yield (astyle.style_error, "%s: %s" % (classname, self))
775
yield (astyle.style_error, classname)
776
xrepr.when_type(Exception)(xrepr_exception)
779
def xrepr_listtuple(self, mode="default"):
780
if mode == "header" or mode == "footer":
781
if self.__class__.__module__ == "__builtin__":
782
classname = self.__class__.__name__
784
classname = "%s.%s" % \
785
(self.__class__.__module__,self.__class__.__name__)
786
yield (astyle.style_default,
787
"<%s object with %d items at 0x%x>" % \
788
(classname, len(self), id(self)))
791
if isinstance(self, list):
792
yield (astyle.style_default, "[")
795
yield (astyle.style_default, "(")
797
for (i, subself) in enumerate(self):
799
yield (astyle.style_default, ", ")
800
for part in xrepr(subself, "default"):
802
yield (astyle.style_default, end)
803
xrepr.when_type(list)(xrepr_listtuple)
804
xrepr.when_type(tuple)(xrepr_listtuple)
807
def xrepr_dict(self, mode="default"):
808
if mode == "header" or mode == "footer":
809
if self.__class__.__module__ == "__builtin__":
810
classname = self.__class__.__name__
812
classname = "%s.%s" % \
813
(self.__class__.__module__,self.__class__.__name__)
814
yield (astyle.style_default,
815
"<%s object with %d items at 0x%x>" % \
816
(classname, len(self), id(self)))
819
if isinstance(self, dict):
820
yield (astyle.style_default, "{")
823
yield (astyle.style_default, "dictproxy((")
825
for (i, (key, value)) in enumerate(self.iteritems()):
827
yield (astyle.style_default, ", ")
828
for part in xrepr(key, "default"):
830
yield (astyle.style_default, ": ")
831
for part in xrepr(value, "default"):
833
yield (astyle.style_default, end)
834
xrepr.when_type(dict)(xrepr_dict)
835
xrepr.when_type(types.DictProxyType)(xrepr_dict)
838
def upgradexattr(attr):
840
Convert an attribute descriptor string to a real descriptor object.
842
If attr already is a descriptor object return if unmodified. A
843
``SelfDescriptor`` will be returned if ``attr`` is ``None``. ``"foo"``
844
returns an ``AttributeDescriptor`` for the attribute named ``"foo"``.
845
``"foo()"`` returns a ``MethodDescriptor`` for the method named ``"foo"``.
846
``"-foo"`` will return an ``IterAttributeDescriptor`` for the attribute
847
named ``"foo"`` and ``"-foo()"`` will return an ``IterMethodDescriptor``
848
for the method named ``"foo"``. Furthermore integer will return the appropriate
849
``IndexDescriptor`` and callables will return a ``FunctionDescriptor``.
852
return selfdescriptor
853
elif isinstance(attr, Descriptor):
855
elif isinstance(attr, str):
856
if attr.endswith("()"):
857
if attr.startswith("-"):
858
return IterMethodDescriptor(attr[1:-2])
860
return MethodDescriptor(attr[:-2])
862
if attr.startswith("-"):
863
return IterAttributeDescriptor(attr[1:])
865
return AttributeDescriptor(attr)
866
elif isinstance(attr, (int, long)):
867
return IndexDescriptor(attr)
869
return FunctionDescriptor(attr)
871
raise TypeError("can't handle descriptor %r" % attr)
874
def xattrs(item, mode="default"):
876
Generic function that returns an iterable of attribute descriptors
877
to be used for displaying the attributes ob the object ``item`` in display
880
There are two possible modes:
883
The ``Display`` object wants to display a detailed list of the object
887
The ``Display`` object wants to display the object in a list view.
889
If no implementation is registered for the object ``item`` ``xattrs`` falls
890
back to trying the ``__xattrs__`` method of the object. If this doesn't
891
exist either, ``dir(item)`` is used for ``"detail"`` mode and ``(None,)``
892
for ``"default"`` mode.
894
The implementation must yield attribute descriptors (see the class
895
``Descriptor`` for more info). The ``__xattrs__`` method may also return
896
attribute descriptor strings (and ``None``) which will be converted to real
897
descriptors by ``upgradexattr()``.
900
func = item.__xattrs__
901
except AttributeError:
903
for attrname in dir(item):
904
yield AttributeDescriptor(attrname)
908
for attr in func(mode):
909
yield upgradexattr(attr)
910
xattrs = simplegeneric.generic(xattrs)
913
def xattrs_complex(self, mode="default"):
915
return (AttributeDescriptor("real"), AttributeDescriptor("imag"))
916
return (selfdescriptor,)
917
xattrs.when_type(complex)(xattrs_complex)
922
itermeth = item.__class__.__iter__
923
except (AttributeError, TypeError):
925
return itermeth is dict.__iter__ or itermeth is types.DictProxyType.__iter__
929
if not isinstance(item, basestring):
932
itermeth = item.__class__.__iter__
933
except AttributeError:
935
return False # ``__iter__`` has been redefined
940
Generic function that implements iteration for pipeline expression. If no
941
implementation is registered for ``item`` ``xiter`` falls back to ``iter``.
944
func = item.__xiter__
945
except AttributeError:
948
fields = ("key", "value")
949
for (key, value) in item.iteritems():
950
yield Fields(fields, key=key, value=value)
952
elif isinstance(item, new.module):
954
fields = ("key", "value")
955
for key in sorted(item.__dict__):
956
yield Fields(fields, key=key, value=getattr(item, key))
960
raise ValueError("can't enter empty string")
961
lines = item.splitlines()
970
return iter(func()) # iter() just to be safe
971
xiter = simplegeneric.generic(xiter)
976
Chains multiple ``Table``s into one.
979
def __init__(self, *iters):
983
return itertools.chain(*self.iters)
985
def __xrepr__(self, mode="default"):
986
if mode == "header" or mode == "footer":
987
for (i, item) in enumerate(self.iters):
989
yield (astyle.style_default, "+")
990
if isinstance(item, Pipe):
991
yield (astyle.style_default, "(")
992
for part in xrepr(item, mode):
994
if isinstance(item, Pipe):
995
yield (astyle.style_default, ")")
997
yield (astyle.style_default, repr(self))
1000
args = ", ".join([repr(it) for it in self.iters])
1001
return "%s.%s(%s)" % \
1002
(self.__class__.__module__, self.__class__.__name__, args)
1005
class ifile(path.path):
1007
file (or directory) object.
1011
return self.stat().st_mode
1012
mode = property(getmode, None, None, "Access mode")
1016
(stat.S_ISREG, "file"),
1017
(stat.S_ISDIR, "dir"),
1018
(stat.S_ISCHR, "chardev"),
1019
(stat.S_ISBLK, "blockdev"),
1020
(stat.S_ISFIFO, "fifo"),
1021
(stat.S_ISLNK, "symlink"),
1022
(stat.S_ISSOCK,"socket"),
1024
lstat = self.lstat()
1025
if lstat is not None:
1026
types = set([text for (func, text) in data if func(lstat.st_mode)])
1030
types.update([text for (func, text) in data if func(m)])
1031
return ", ".join(types)
1032
type = property(gettype, None, None, "file type (file, directory, link, etc.)")
1034
def getmodestr(self):
1037
(stat.S_IRUSR, "-r"),
1038
(stat.S_IWUSR, "-w"),
1039
(stat.S_IXUSR, "-x"),
1040
(stat.S_IRGRP, "-r"),
1041
(stat.S_IWGRP, "-w"),
1042
(stat.S_IXGRP, "-x"),
1043
(stat.S_IROTH, "-r"),
1044
(stat.S_IWOTH, "-w"),
1045
(stat.S_IXOTH, "-x"),
1047
return "".join([text[bool(m&bit)] for (bit, text) in data])
1049
modestr = property(getmodestr, None, None, "Access mode as string")
1051
def getblocks(self):
1052
return self.stat().st_blocks
1053
blocks = property(getblocks, None, None, "File size in blocks")
1055
def getblksize(self):
1056
return self.stat().st_blksize
1057
blksize = property(getblksize, None, None, "Filesystem block size")
1060
return self.stat().st_dev
1061
dev = property(getdev)
1064
return self.stat().st_nlink
1065
nlink = property(getnlink, None, None, "Number of links")
1068
return self.stat().st_uid
1069
uid = property(getuid, None, None, "User id of file owner")
1072
return self.stat().st_gid
1073
gid = property(getgid, None, None, "Group id of file owner")
1078
return pwd.getpwuid(stat.st_uid).pw_name
1081
owner = property(getowner, None, None, "Owner name (or id)")
1086
return grp.getgrgid(stat.st_gid).gr_name
1089
group = property(getgroup, None, None, "Group name (or id)")
1092
return datetime.datetime.utcfromtimestamp(self.atime)
1093
adate = property(getadate, None, None, "Access date")
1096
return datetime.datetime.utcfromtimestamp(self.ctime)
1097
cdate = property(getcdate, None, None, "Creation date")
1100
return datetime.datetime.utcfromtimestamp(self.mtime)
1101
mdate = property(getmdate, None, None, "Modification date")
1105
Return MIME type guessed from the extension.
1107
return mimetypes.guess_type(self.basename())[0]
1111
Return guessed compression (like "compress" or "gzip").
1113
return mimetypes.guess_type(self.basename())[1]
1116
return "ifile(%s)" % path._base.__repr__(self)
1118
if sys.platform == "win32":
1119
defaultattrs = (None, "type", "size", "modestr", "mdate")
1121
defaultattrs = (None, "type", "size", "modestr", "owner", "group", "mdate")
1123
def __xattrs__(self, mode="default"):
1124
if mode == "detail":
1162
return self.defaultattrs
1165
def xiter_ifile(self):
1167
yield (self / os.pardir).abspath()
1168
for child in sorted(self.listdir()):
1175
xiter.when_type(ifile)(xiter_ifile)
1178
# We need to implement ``xrepr`` for ``ifile`` as a generic function, because
1179
# otherwise ``xrepr_str`` would kick in.
1180
def xrepr_ifile(self, mode="default"):
1184
style = astyle.style_dir
1187
style = astyle.style_file
1190
style = astyle.style_default
1191
if mode in ("cell", "header", "footer"):
1192
abspath = repr(path._base(self.normpath()))
1193
if abspath.startswith("u"):
1194
abspath = abspath[2:-1]
1196
abspath = abspath[1:-1]
1198
yield (style, abspath)
1200
yield (style, "%s(%s)" % (name, abspath))
1202
yield (style, repr(self))
1203
xrepr.when_type(ifile)(xrepr_ifile)
1208
List the current (or a specified) directory.
1213
>>> ils("/usr/local/lib/python2.4")
1216
def __init__(self, base=os.curdir, dirs=True, files=True):
1217
self.base = os.path.expanduser(base)
1222
base = ifile(self.base)
1223
yield (base / os.pardir).abspath()
1224
for child in sorted(base.listdir()):
1232
if not child.isdir():
1235
def __xrepr__(self, mode="default"):
1236
return xrepr(ifile(self.base), mode)
1239
return "%s.%s(%r)" % \
1240
(self.__class__.__module__, self.__class__.__name__, self.base)
1245
List all files and directories matching a specified pattern.
1246
(See ``glob.glob()`` for more info.).
1252
def __init__(self, glob):
1256
for name in glob.glob(self.glob):
1259
def __xrepr__(self, mode="default"):
1260
if mode == "header" or mode == "footer" or mode == "cell":
1261
yield (astyle.style_default,
1262
"%s(%r)" % (self.__class__.__name__, self.glob))
1264
yield (astyle.style_default, repr(self))
1267
return "%s.%s(%r)" % \
1268
(self.__class__.__module__, self.__class__.__name__, self.glob)
1273
List all files and directories in a directory and it's subdirectory::
1276
>>> iwalk("/usr/local/lib/python2.4")
1279
def __init__(self, base=os.curdir, dirs=True, files=True):
1280
self.base = os.path.expanduser(base)
1285
for (dirpath, dirnames, filenames) in os.walk(self.base):
1287
for name in sorted(dirnames):
1288
yield ifile(os.path.join(dirpath, name))
1290
for name in sorted(filenames):
1291
yield ifile(os.path.join(dirpath, name))
1293
def __xrepr__(self, mode="default"):
1294
if mode == "header" or mode == "footer" or mode == "cell":
1295
yield (astyle.style_default,
1296
"%s(%r)" % (self.__class__.__name__, self.base))
1298
yield (astyle.style_default, repr(self))
1301
return "%s.%s(%r)" % \
1302
(self.__class__.__module__, self.__class__.__name__, self.base)
1305
class ipwdentry(object):
1307
``ipwdentry`` objects encapsulate entries in the Unix user account and
1310
def __init__(self, id):
1314
def __eq__(self, other):
1315
return self.__class__ is other.__class__ and self._id == other._id
1317
def __ne__(self, other):
1318
return self.__class__ is not other.__class__ or self._id != other._id
1320
def _getentry(self):
1321
if self._entry is None:
1322
if isinstance(self._id, basestring):
1323
self._entry = pwd.getpwnam(self._id)
1325
self._entry = pwd.getpwuid(self._id)
1329
if isinstance(self._id, basestring):
1332
return self._getentry().pw_name
1333
name = property(getname, None, None, "User name")
1335
def getpasswd(self):
1336
return self._getentry().pw_passwd
1337
passwd = property(getpasswd, None, None, "Password")
1340
if isinstance(self._id, basestring):
1341
return self._getentry().pw_uid
1344
uid = property(getuid, None, None, "User id")
1347
return self._getentry().pw_gid
1348
gid = property(getgid, None, None, "Primary group id")
1351
return igrpentry(self.gid)
1352
group = property(getgroup, None, None, "Group")
1355
return self._getentry().pw_gecos
1356
gecos = property(getgecos, None, None, "Information (e.g. full user name)")
1359
return self._getentry().pw_dir
1360
dir = property(getdir, None, None, "$HOME directory")
1363
return self._getentry().pw_shell
1364
shell = property(getshell, None, None, "Login shell")
1366
def __xattrs__(self, mode="default"):
1367
return ("name", "passwd", "uid", "gid", "gecos", "dir", "shell")
1370
return "%s.%s(%r)" % \
1371
(self.__class__.__module__, self.__class__.__name__, self._id)
1376
List all entries in the Unix user account and password database.
1380
>>> ipwd | isort("uid")
1383
for entry in pwd.getpwall():
1384
yield ipwdentry(entry.pw_name)
1386
def __xrepr__(self, mode="default"):
1387
if mode == "header" or mode == "footer" or mode == "cell":
1388
yield (astyle.style_default, "%s()" % self.__class__.__name__)
1390
yield (astyle.style_default, repr(self))
1393
class igrpentry(object):
1395
``igrpentry`` objects encapsulate entries in the Unix group database.
1397
def __init__(self, id):
1401
def __eq__(self, other):
1402
return self.__class__ is other.__class__ and self._id == other._id
1404
def __ne__(self, other):
1405
return self.__class__ is not other.__class__ or self._id != other._id
1407
def _getentry(self):
1408
if self._entry is None:
1409
if isinstance(self._id, basestring):
1410
self._entry = grp.getgrnam(self._id)
1412
self._entry = grp.getgrgid(self._id)
1416
if isinstance(self._id, basestring):
1419
return self._getentry().gr_name
1420
name = property(getname, None, None, "Group name")
1422
def getpasswd(self):
1423
return self._getentry().gr_passwd
1424
passwd = property(getpasswd, None, None, "Password")
1427
if isinstance(self._id, basestring):
1428
return self._getentry().gr_gid
1431
gid = property(getgid, None, None, "Group id")
1434
return self._getentry().gr_mem
1435
mem = property(getmem, None, None, "Members")
1437
def __xattrs__(self, mode="default"):
1438
return ("name", "passwd", "gid", "mem")
1440
def __xrepr__(self, mode="default"):
1441
if mode == "header" or mode == "footer" or mode == "cell":
1442
yield (astyle.style_default, "group ")
1444
yield (astyle.style_default, self.name)
1446
if isinstance(self._id, basestring):
1447
yield (astyle.style_default, self.name_id)
1449
yield (astyle.style_type_number, str(self._id))
1451
yield (astyle.style_default, repr(self))
1454
for member in self.mem:
1455
yield ipwdentry(member)
1458
return "%s.%s(%r)" % \
1459
(self.__class__.__module__, self.__class__.__name__, self._id)
1464
This ``Table`` lists all entries in the Unix group database.
1467
for entry in grp.getgrall():
1468
yield igrpentry(entry.gr_name)
1470
def __xrepr__(self, mode="default"):
1471
if mode == "header" or mode == "footer":
1472
yield (astyle.style_default, "%s()" % self.__class__.__name__)
1474
yield (astyle.style_default, repr(self))
1477
class Fields(object):
1478
def __init__(self, fieldnames, **fields):
1479
self.__fieldnames = [upgradexattr(fieldname) for fieldname in fieldnames]
1480
for (key, value) in fields.iteritems():
1481
setattr(self, key, value)
1483
def __xattrs__(self, mode="default"):
1484
return self.__fieldnames
1486
def __xrepr__(self, mode="default"):
1488
if mode == "header" or mode == "cell":
1489
yield (astyle.style_default, self.__class__.__name__)
1490
yield (astyle.style_default, "(")
1491
for (i, f) in enumerate(self.__fieldnames):
1493
yield (astyle.style_default, ", ")
1494
yield (astyle.style_default, f.name())
1495
yield (astyle.style_default, "=")
1496
for part in xrepr(getattr(self, f), "default"):
1498
yield (astyle.style_default, ")")
1499
elif mode == "footer":
1500
yield (astyle.style_default, self.__class__.__name__)
1501
yield (astyle.style_default, "(")
1502
for (i, f) in enumerate(self.__fieldnames):
1504
yield (astyle.style_default, ", ")
1505
yield (astyle.style_default, f.name())
1506
yield (astyle.style_default, ")")
1508
yield (astyle.style_default, repr(self))
1511
class FieldTable(Table, list):
1512
def __init__(self, *fields):
1513
Table.__init__(self)
1515
self.fields = fields
1517
def add(self, **fields):
1518
self.append(Fields(self.fields, **fields))
1520
def __xrepr__(self, mode="default"):
1522
if mode == "header" or mode == "footer":
1523
yield (astyle.style_default, self.__class__.__name__)
1524
yield (astyle.style_default, "(")
1525
for (i, f) in enumerate(self.__fieldnames):
1527
yield (astyle.style_default, ", ")
1528
yield (astyle.style_default, f)
1529
yield (astyle.style_default, ")")
1531
yield (astyle.style_default, repr(self))
1534
return "<%s.%s object with fields=%r at 0x%x>" % \
1535
(self.__class__.__module__, self.__class__.__name__,
1536
", ".join(map(repr, self.fields)), id(self))
1540
def __xattrs__(self, mode="default"):
1541
return xrange(len(self))
1543
def __xrepr__(self, mode="default"):
1545
if mode == "header" or mode == "cell" or mode == "footer" or mode == "default":
1546
yield (astyle.style_default, self.__class__.__name__)
1547
yield (astyle.style_default, "(")
1548
for (i, item) in enumerate(self):
1550
yield (astyle.style_default, ", ")
1551
for part in xrepr(item, "default"):
1553
yield (astyle.style_default, ")")
1555
yield (astyle.style_default, repr(self))
1560
List environment variables.
1568
fields = ("key", "value")
1569
for (key, value) in os.environ.iteritems():
1570
yield Fields(fields, key=key, value=value)
1572
def __xrepr__(self, mode="default"):
1573
if mode == "header" or mode == "cell":
1574
yield (astyle.style_default, "%s()" % self.__class__.__name__)
1576
yield (astyle.style_default, repr(self))
1581
IPython input history
1586
>>> ihist(True) (raw mode)
1588
def __init__(self, raw=True):
1594
for line in api.IP.input_hist_raw:
1595
yield line.rstrip("\n")
1597
for line in api.IP.input_hist:
1598
yield line.rstrip("\n")
1601
class Alias(object):
1603
Entry in the alias table
1605
def __init__(self, name, args, command):
1608
self.command = command
1610
def __xattrs__(self, mode="default"):
1611
return ("name", "args", "command")
1614
class ialias(Table):
1625
for (name, (args, command)) in api.IP.alias_table.iteritems():
1626
yield Alias(name, args, command)
1631
This ``Pipe`` turns the input (with must be a pipe outputting lines
1632
or an ``ifile``) into lines of CVS columns.
1634
def __init__(self, **csvargs):
1636
Create an ``icsv`` object. ``cvsargs`` will be passed through as
1637
keyword arguments to ``cvs.reader()``.
1639
self.csvargs = csvargs
1643
if isinstance(input, ifile):
1644
input = input.open("rb")
1645
reader = csv.reader(input, **self.csvargs)
1649
def __xrepr__(self, mode="default"):
1651
if mode == "header" or mode == "footer":
1652
input = getattr(self, "input", None)
1653
if input is not None:
1654
for part in xrepr(input, mode):
1656
yield (astyle.style_default, " | ")
1657
yield (astyle.style_default, "%s(" % self.__class__.__name__)
1658
for (i, (name, value)) in enumerate(self.csvargs.iteritems()):
1660
yield (astyle.style_default, ", ")
1661
yield (astyle.style_default, name)
1662
yield (astyle.style_default, "=")
1663
for part in xrepr(value, "default"):
1665
yield (astyle.style_default, ")")
1667
yield (astyle.style_default, repr(self))
1670
args = ", ".join(["%s=%r" % item for item in self.csvargs.iteritems()])
1671
return "<%s.%s %s at 0x%x>" % \
1672
(self.__class__.__module__, self.__class__.__name__, args, id(self))
1677
Execute a system command and list its output as lines
1678
(similar to ``os.popen()``).
1683
>>> ix("find .") | ifile
1685
def __init__(self, cmd):
1687
self._pipeout = None
1690
(_pipein, self._pipeout) = os.popen4(self.cmd)
1692
for l in self._pipeout:
1693
yield l.rstrip("\r\n")
1694
self._pipeout.close()
1695
self._pipeout = None
1698
if self._pipeout is not None and not self._pipeout.closed:
1699
self._pipeout.close()
1700
self._pipeout = None
1702
def __xrepr__(self, mode="default"):
1703
if mode == "header" or mode == "footer":
1704
yield (astyle.style_default,
1705
"%s(%r)" % (self.__class__.__name__, self.cmd))
1707
yield (astyle.style_default, repr(self))
1710
return "%s.%s(%r)" % \
1711
(self.__class__.__module__, self.__class__.__name__, self.cmd)
1714
class ifilter(Pipe):
1716
Filter an input pipe. Only objects where an expression evaluates to true
1717
(and doesn't raise an exception) are listed.
1721
>>> ils | ifilter("_.isfile() and size>1000")
1722
>>> igrp | ifilter("len(mem)")
1723
>>> sys.modules | ifilter(lambda _:_.value is not None)
1726
def __init__(self, expr, globals=None, errors="raiseifallfail"):
1728
Create an ``ifilter`` object. ``expr`` can be a callable or a string
1729
containing an expression. ``globals`` will be used as the global
1730
namespace for calling string expressions (defaulting to IPython's
1731
user namespace). ``errors`` specifies how exception during evaluation
1732
of ``expr`` are handled:
1735
drop all items that have errors;
1738
keep all items that have errors;
1741
keep the exception of all items that have errors;
1744
raise the exception;
1746
``"raiseifallfail"``
1747
raise the first exception if all items have errors; otherwise drop
1748
those with errors (this is the default).
1751
self.globals = globals
1752
self.errors = errors
1755
if callable(self.expr):
1758
g = getglobals(self.globals)
1759
expr = compile(self.expr, "ipipe-expression", "eval")
1761
return eval(expr, g, AttrNamespace(item))
1765
for item in xiter(self.input):
1770
except (KeyboardInterrupt, SystemExit):
1772
except Exception, exc:
1773
if self.errors == "drop":
1774
pass # Ignore errors
1775
elif self.errors == "keep":
1777
elif self.errors == "keeperror":
1779
elif self.errors == "raise":
1781
elif self.errors == "raiseifallfail":
1782
if exc_info is None:
1783
exc_info = sys.exc_info()
1784
if not ok and exc_info is not None:
1785
raise exc_info[0], exc_info[1], exc_info[2]
1787
def __xrepr__(self, mode="default"):
1788
if mode == "header" or mode == "footer":
1789
input = getattr(self, "input", None)
1790
if input is not None:
1791
for part in xrepr(input, mode):
1793
yield (astyle.style_default, " | ")
1794
yield (astyle.style_default, "%s(" % self.__class__.__name__)
1795
for part in xrepr(self.expr, "default"):
1797
yield (astyle.style_default, ")")
1799
yield (astyle.style_default, repr(self))
1802
return "<%s.%s expr=%r at 0x%x>" % \
1803
(self.__class__.__module__, self.__class__.__name__,
1804
self.expr, id(self))
1809
Evaluate an expression for each object in the input pipe.
1813
>>> ils | ieval("_.abspath()")
1814
>>> sys.path | ieval(ifile)
1817
def __init__(self, expr, globals=None, errors="raiseifallfail"):
1819
Create an ``ieval`` object. ``expr`` can be a callable or a string
1820
containing an expression. For the meaning of ``globals`` and
1821
``errors`` see ``ifilter``.
1824
self.globals = globals
1825
self.errors = errors
1828
if callable(self.expr):
1831
g = getglobals(self.globals)
1832
expr = compile(self.expr, "ipipe-expression", "eval")
1834
return eval(expr, g, AttrNamespace(item))
1838
for item in xiter(self.input):
1841
except (KeyboardInterrupt, SystemExit):
1843
except Exception, exc:
1844
if self.errors == "drop":
1845
pass # Ignore errors
1846
elif self.errors == "keep":
1848
elif self.errors == "keeperror":
1850
elif self.errors == "raise":
1852
elif self.errors == "raiseifallfail":
1853
if exc_info is None:
1854
exc_info = sys.exc_info()
1855
if not ok and exc_info is not None:
1856
raise exc_info[0], exc_info[1], exc_info[2]
1858
def __xrepr__(self, mode="default"):
1859
if mode == "header" or mode == "footer":
1860
input = getattr(self, "input", None)
1861
if input is not None:
1862
for part in xrepr(input, mode):
1864
yield (astyle.style_default, " | ")
1865
yield (astyle.style_default, "%s(" % self.__class__.__name__)
1866
for part in xrepr(self.expr, "default"):
1868
yield (astyle.style_default, ")")
1870
yield (astyle.style_default, repr(self))
1873
return "<%s.%s expr=%r at 0x%x>" % \
1874
(self.__class__.__module__, self.__class__.__name__,
1875
self.expr, id(self))
1880
Enumerate the input pipe (i.e. wrap each input object in an object
1881
with ``index`` and ``object`` attributes).
1885
>>> xrange(20) | ieval("_,_*_") | ienum | ifilter("index % 2 == 0") | ieval("object")
1888
fields = ("index", "object")
1889
for (index, object) in enumerate(xiter(self.input)):
1890
yield Fields(fields, index=index, object=object)
1895
Sorts the input pipe.
1899
>>> ils | isort("size")
1900
>>> ils | isort("_.isdir(), _.lower()", reverse=True)
1903
def __init__(self, key=None, globals=None, reverse=False):
1905
Create an ``isort`` object. ``key`` can be a callable or a string
1906
containing an expression (or ``None`` in which case the items
1907
themselves will be sorted). If ``reverse`` is true the sort order
1908
will be reversed. For the meaning of ``globals`` see ``ifilter``.
1911
self.globals = globals
1912
self.reverse = reverse
1915
if self.key is None:
1916
items = sorted(xiter(self.input), reverse=self.reverse)
1917
elif callable(self.key):
1918
items = sorted(xiter(self.input), key=self.key, reverse=self.reverse)
1920
g = getglobals(self.globals)
1921
key = compile(self.key, "ipipe-expression", "eval")
1923
return eval(key, g, AttrNamespace(item))
1924
items = sorted(xiter(self.input), key=realkey, reverse=self.reverse)
1928
def __xrepr__(self, mode="default"):
1929
if mode == "header" or mode == "footer":
1930
input = getattr(self, "input", None)
1931
if input is not None:
1932
for part in xrepr(input, mode):
1934
yield (astyle.style_default, " | ")
1935
yield (astyle.style_default, "%s(" % self.__class__.__name__)
1936
for part in xrepr(self.key, "default"):
1939
yield (astyle.style_default, ", ")
1940
for part in xrepr(True, "default"):
1942
yield (astyle.style_default, ")")
1944
yield (astyle.style_default, repr(self))
1947
return "<%s.%s key=%r reverse=%r at 0x%x>" % \
1948
(self.__class__.__module__, self.__class__.__name__,
1949
self.key, self.reverse, id(self))
1952
tab = 3 # for expandtabs()
1955
if isinstance(field, str):
1956
text = repr(field.expandtabs(tab))[1:-1]
1957
elif isinstance(field, unicode):
1958
text = repr(field.expandtabs(tab))[2:-1]
1959
elif isinstance(field, datetime.datetime):
1960
# Don't use strftime() here, as this requires year >= 1900
1961
text = "%04d-%02d-%02d %02d:%02d:%02d.%06d" % \
1962
(field.year, field.month, field.day,
1963
field.hour, field.minute, field.second, field.microsecond)
1964
elif isinstance(field, datetime.date):
1965
text = "%04d-%02d-%02d" % (field.year, field.month, field.day)
1971
class Display(object):
1972
class __metaclass__(type):
1973
def __ror__(self, input):
1974
return input | self()
1976
def __init__(self, input=None):
1979
def __ror__(self, input):
1987
class iless(Display):
1988
cmd = "less --quit-if-one-screen --LONG-PROMPT --LINE-NUMBERS --chop-long-lines --shift=8 --RAW-CONTROL-CHARS"
1992
pager = os.popen(self.cmd, "w")
1994
for item in xiter(self.input):
1996
for attr in xattrs(item, "default"):
2001
attr = upgradexattr(attr)
2002
if not isinstance(attr, SelfDescriptor):
2003
pager.write(attr.name())
2005
pager.write(str(attr.value(item)))
2009
except Exception, exc:
2010
print "%s: %s" % (exc.__class__.__name__, str(exc))
2013
class _RedirectIO(object):
2014
def __init__(self,*args,**kwargs):
2016
Map the system output streams to self.
2018
self.stream = StringIO.StringIO()
2019
self.stdout = sys.stdout
2021
self.stderr = sys.stderr
2024
def write(self, text):
2026
Write both to screen and to self.
2028
self.stream.write(text)
2029
self.stdout.write(text)
2033
def writelines(self, lines):
2035
Write lines both to screen and to self.
2037
self.stream.writelines(lines)
2038
self.stdout.writelines(lines)
2043
Restore the default system streams.
2047
sys.stdout = self.stdout
2048
sys.stderr = self.stderr
2053
Execute a python string and capture any output to stderr/stdout.
2058
>>> icap("for i in range(10): print i, time.sleep(0.1)")
2061
def __init__(self, expr, globals=None):
2063
self.globals = globals
2066
exec(expr, getglobals(globals))
2069
self.stream = log.stream
2073
for line in self.stream:
2074
yield line.rstrip("\r\n")
2076
def __xrepr__(self, mode="default"):
2077
if mode == "header" or mode == "footer":
2078
yield (astyle.style_default,
2079
"%s(%r)" % (self.__class__.__name__, self.expr))
2081
yield (astyle.style_default, repr(self))
2084
return "%s.%s(%r)" % \
2085
(self.__class__.__module__, self.__class__.__name__, self.expr)
2088
def xformat(value, mode, maxlength):
2092
text = astyle.Text()
2093
for (style, part) in xrepr(value, mode):
2094
# only consider the first result
2096
if isinstance(style, int):
2097
# (style, text) really is (alignment, stop)
2104
if not isinstance(style, int):
2105
text.append((style, part))
2107
if width >= maxlength and not full:
2108
text.append((astyle.style_ellisis, "..."))
2111
if align is None: # default to left alignment
2113
return (align, width, text)
2119
class idump(Display):
2120
# The approximate maximum length of a column entry
2123
# Style for column names
2124
style_header = astyle.Style.fromstr("white:black:bold")
2126
def __init__(self, input=None, *attrs):
2127
Display.__init__(self, input)
2128
self.attrs = [upgradexattr(attr) for attr in attrs]
2129
self.headerpadchar = " "
2130
self.headersepchar = "|"
2131
self.datapadchar = " "
2132
self.datasepchar = "|"
2135
stream = genutils.Term.cout
2140
for item in xiter(self.input):
2144
attrs = xattrs(item, "default")
2146
if attr not in attrset:
2147
allattrs.append(attr)
2149
colwidths[attr] = len(attr.name())
2151
value = attr.value(item)
2152
except (KeyboardInterrupt, SystemExit):
2154
except Exception, exc:
2156
(align, width, text) = xformat(value, "cell", self.maxattrlength)
2157
colwidths[attr] = max(colwidths[attr], width)
2158
# remember alignment, length and colored parts
2159
row[attr] = (align, width, text)
2163
for (i, attr) in enumerate(allattrs):
2164
attrname = attr.name()
2165
self.style_header(attrname).write(stream)
2166
spc = colwidths[attr] - len(attrname)
2167
if i < len(colwidths)-1:
2168
stream.write(self.headerpadchar*spc)
2169
stream.write(self.headersepchar)
2173
for (i, attr) in enumerate(allattrs):
2174
(align, width, text) = row[attr]
2175
spc = colwidths[attr] - width
2178
if i < len(colwidths)-1:
2179
stream.write(self.datapadchar*spc)
2181
spc = colwidths[attr] - width
2184
stream.write(self.datapadchar*spc1)
2186
if i < len(colwidths)-1:
2187
stream.write(self.datapadchar*spc2)
2189
stream.write(self.datapadchar*spc)
2191
if i < len(colwidths)-1:
2192
stream.write(self.datasepchar)
2196
class AttributeDetail(Table):
2198
``AttributeDetail`` objects are use for displaying a detailed list of object
2201
def __init__(self, object, descriptor):
2202
self.object = object
2203
self.descriptor = descriptor
2206
return self.descriptor.iter(self.object)
2209
return self.descriptor.name()
2212
return self.descriptor.attrtype(self.object)
2214
def valuetype(self):
2215
return self.descriptor.valuetype(self.object)
2218
return self.descriptor.doc(self.object)
2221
return self.descriptor.shortdoc(self.object)
2224
return self.descriptor.value(self.object)
2226
def __xattrs__(self, mode="default"):
2227
attrs = ("name()", "attrtype()", "valuetype()", "value()", "shortdoc()")
2228
if mode == "detail":
2232
def __xrepr__(self, mode="default"):
2234
valuetype = self.valuetype()
2235
if valuetype is not noitem:
2236
for part in xrepr(valuetype):
2238
yield (astyle.style_default, " ")
2239
yield (astyle.style_default, self.attrtype())
2240
yield (astyle.style_default, " ")
2241
yield (astyle.style_default, self.name())
2242
yield (astyle.style_default, " of ")
2243
for part in xrepr(self.object):
2248
from ibrowse import ibrowse
2250
# No curses (probably Windows) => try igrid
2252
from igrid import igrid
2254
# no wx either => use ``idump`` as the default display.
2255
defaultdisplay = idump
2257
defaultdisplay = igrid
2258
__all__.append("igrid")
2260
defaultdisplay = ibrowse
2261
__all__.append("ibrowse")
2264
# If we're running under IPython, register our objects with IPython's
2265
# generic function ``result_display``, else install a displayhook
2266
# directly as sys.displayhook
2267
if generics is not None:
2268
def display_display(obj):
2269
return obj.display()
2270
generics.result_display.when_type(Display)(display_display)
2272
def display_tableobject(obj):
2273
return display_display(defaultdisplay(obj))
2274
generics.result_display.when_type(Table)(display_tableobject)
2276
def display_tableclass(obj):
2277
return display_tableobject(obj())
2278
generics.result_display.when_type(Table.__metaclass__)(display_tableclass)
2280
def installdisplayhook():
2281
_originalhook = sys.displayhook
2282
def displayhook(obj):
2283
if isinstance(obj, type) and issubclass(obj, Table):
2285
if isinstance(obj, Table):
2286
obj = defaultdisplay(obj)
2287
if isinstance(obj, Display):
2288
return obj.display()
2291
sys.displayhook = displayhook
2292
installdisplayhook()