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