]> git.wh0rd.org Git - home.git/blob - .ipython/profile_default/startup/50-dump.py
e1910eae62059286bf136ff198338a8db967d73f
[home.git] / .ipython / profile_default / startup / 50-dump.py
1 #!/usr/bin/python
2 # Released into the public domain.
3 # Written by Mike Frysinger <vapier>.
4
5 """Module for diving into python objects."""
6
7 from __future__ import print_function
8
9
10 class Dump(object):
11
12     try:
13         from cStringIO import StringIO
14     except:
15         from io import StringIO
16     import datetime
17     import logging
18     import pydoc
19     import os
20     import sys
21     import types
22
23     MAX_DEPTH = 1
24
25     # Objects that hold multiple objects (can be looped over).
26     TYPES_ITERABLES = (
27         types.GeneratorType,
28         types.ListType,
29         types.TupleType,
30     )
31
32     # Objects that we shouldn't really probe.
33     TYPES_CALLABLE = (
34         types.FunctionType,
35         types.LambdaType,
36     )
37
38     # Simple objects we don't decode further.
39     TYPES_SCALAR = (
40         types.BooleanType,
41         types.ComplexType,
42         types.FloatType,
43         types.IntType,
44         types.LongType,
45         types.NoneType,
46         types.StringType,
47         types.UnicodeType,
48
49         types.ClassType,
50         types.TypeType,
51     )
52
53     # Objects that are dictionary based.
54     TYPES_DICT = (
55         types.DictType,
56         types.DictionaryType,
57     )
58
59     # Standard python objects we don't normally expand.
60     TYPES_STANDARD = (
61         datetime.date,
62         datetime.datetime,
63         datetime.time,
64         logging.Logger
65     )
66
67     # Color logic.
68     _C = lambda x: '\033[%im' % x
69     def C(self, m, c):
70         return '%s%s%s' % (c, m, self.NORMAL)
71     NORMAL    = _C(0)
72     BOLD      = _C(1)
73     UNDERLINE = _C(4)
74     #BLACK     = _C()
75
76     PURPLE    = _C(95)
77     CYAN      = _C(96)
78     DARKCYAN  = _C(36)
79     BLUE      = _C(94)
80     GREEN     = _C(92)
81     YELLOW    = _C(93)
82     RED       = _C(91)
83
84     def __init__(self, obj, depth=None, out=None, linelim=150,
85                  show_internal=False, show_all=False, show_std=False):
86         if out is None:
87             out = self.StringIO()
88             #out = self.sys.stdout
89         self.out = out
90
91         self.depth = depth if depth else self.MAX_DEPTH
92         self.line_limit = linelim
93         self.show_internal = show_internal
94         self.show_all = show_all
95         self.show_std = show_std
96
97         self.seen = set()
98         self.dump(obj)
99
100         if hasattr(out, 'getvalue'):
101             self.pydoc.pager(out.getvalue())
102
103         return None
104
105     def trunc(self, s):
106         """Truncate |s| length to self.line_limit bytes"""
107         if len(s) > self.line_limit:
108             s = '%s %s' % (s[0:self.line_limit],
109                            self.C('<truncated>', self.RED))
110         return s
111
112     def dump(self, obj, depth=0, name=None):
113         """Dump |obj| with |name|"""
114         indent = '    ' * depth
115         def w(msg, indent=indent, color=None):
116             for line in msg.splitlines():
117                 if color:
118                     line = self.C(line, color)
119                 self.out.write('%s%s\n' % (indent, line))
120         def d(obj, **kwargs):
121             try:
122                 self.dump(obj, depth=depth + 1, **kwargs)
123             except Exception as e:
124                 w(' <error probing>: %s' % (e,), color=self.RED)
125                 raise
126
127         if ((not self.show_std and isinstance(obj, self.TYPES_STANDARD)) or
128             isinstance(obj, self.TYPES_SCALAR)):
129             w('%s: %s' % (self.C(name, self.BOLD), obj), indent=indent[:-2])
130             return
131
132         try:
133             if obj in self.seen:
134                 w('%s: %s' % (self.C(name, self.BOLD),
135                               self.C('<loop>', self.RED)), indent=indent[:-2])
136                 return
137             self.seen.add(obj)
138         except TypeError:
139             pass
140
141         if name:
142             w('%s' % (name,), color=self.BOLD, indent=indent[:-2])
143
144         objr = repr(obj)
145         objs = str(obj)
146         if objr == objs:
147             w('%s: %s' % (type(obj), self.trunc(objs),))
148         else:
149             w('Object.type: %s' % (type(obj),))
150             w('      .repr: %s' % (self.trunc(objr),))
151             w('      .str : %s' % (self.trunc(objs),))
152
153         if depth > self.depth:
154             w('<stop; depth limit hit at %i>' % (depth,), color=self.RED)
155             return
156
157         if isinstance(obj, self.TYPES_ITERABLES):
158             # Iterable types.
159             for i, o in enumerate(obj):
160                 d(o, name='[%i]' % (i,))
161         elif isinstance(obj, self.TYPES_SCALAR):
162             # Scalar types; already shown above.
163             pass
164         elif isinstance(obj, self.TYPES_DICT):
165             # Dictionary types.
166             for k, v in obj.items():
167                 d(v, name='{%r}' % (k,))
168         elif isinstance(obj, self.TYPES_STANDARD):
169             # Standard types; already shown above.
170             pass
171         elif isinstance(obj, self.TYPES_CALLABLE):
172             # Callable functions.
173             doc = getattr(obj, 'func_doc', None)
174             if doc:
175                 w('"""%s"""' % (doc.strip(),), indent=indent + '  ',
176                   color=self.BLUE)
177         else:
178             # Unknown type; probe it!
179             doc = getattr(obj, '__doc__', None)
180             if doc:
181                 w('"""%s"""' % (doc.strip(),), indent=indent + '  ',
182                   color=self.BLUE)
183
184             for k, v in getattr(obj, '__dict__', {}).items():
185                 d(v, name='{%r}' % (k,))
186
187             for k in dir(obj):
188                 try:
189                     s = self.trunc(repr(getattr(obj, k)))
190                 except Exception as e:
191                     w('  %s: %s' % (self.C(k, self.BOLD),
192                                    self.C('<error> %s' % str(e), self.RED)))
193                     continue
194
195                 if k.startswith('__'):
196                     if self.show_all or not k.endswith('__'):
197                         w('  %s (skipping): %s' % (self.C(k, self.BOLD), s))
198                 elif self.show_internal or not k.startswith('_'):
199                     d(getattr(obj, k), name=k)
200
201
202 def dump(*args, **kwargs):
203     d = Dump(*args, **kwargs)
204     del d