]> git.wh0rd.org - home.git/blame - .ipython/profile_default/startup/50-dump.py
ipython: fix up to work w/ipython-5 and py3
[home.git] / .ipython / profile_default / startup / 50-dump.py
CommitLineData
c4372a0b
MF
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
7from __future__ import print_function
8
9
10class Dump(object):
11
722f573c
MF
12 try:
13 from cStringIO import StringIO
14 except:
15 from io import StringIO
c4372a0b
MF
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,
22072cde
MF
28 list,
29 tuple,
c4372a0b
MF
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 = (
22072cde
MF
40 bool,
41 complex,
42 float,
43 int,
44 #types.LongType,
45 type(None),
46 bytes,
47 str,
48
49 type,
c4372a0b
MF
50 )
51
52 # Objects that are dictionary based.
53 TYPES_DICT = (
22072cde 54 dict,
c4372a0b
MF
55 )
56
57 # Standard python objects we don't normally expand.
58 TYPES_STANDARD = (
59 datetime.date,
60 datetime.datetime,
61 datetime.time,
62 logging.Logger
63 )
64
65 # Color logic.
66 _C = lambda x: '\033[%im' % x
67 def C(self, m, c):
68 return '%s%s%s' % (c, m, self.NORMAL)
69 NORMAL = _C(0)
70 BOLD = _C(1)
71 UNDERLINE = _C(4)
72 #BLACK = _C()
73
74 PURPLE = _C(95)
75 CYAN = _C(96)
76 DARKCYAN = _C(36)
77 BLUE = _C(94)
78 GREEN = _C(92)
79 YELLOW = _C(93)
80 RED = _C(91)
81
82 def __init__(self, obj, depth=None, out=None, linelim=150,
83 show_internal=False, show_all=False, show_std=False):
84 if out is None:
722f573c 85 out = self.StringIO()
c4372a0b
MF
86 #out = self.sys.stdout
87 self.out = out
88
89 self.depth = depth if depth else self.MAX_DEPTH
90 self.line_limit = linelim
91 self.show_internal = show_internal
92 self.show_all = show_all
93 self.show_std = show_std
94
95 self.seen = set()
96 self.dump(obj)
97
98 if hasattr(out, 'getvalue'):
99 self.pydoc.pager(out.getvalue())
100
101 return None
102
103 def trunc(self, s):
104 """Truncate |s| length to self.line_limit bytes"""
105 if len(s) > self.line_limit:
106 s = '%s %s' % (s[0:self.line_limit],
107 self.C('<truncated>', self.RED))
108 return s
109
110 def dump(self, obj, depth=0, name=None):
22072cde
MF
111 """Dump |obj| with |name|.
112
113 Args:
114 obj: The object to dump.
115 depth: How deep to recursively dive.
116 name: The name?
117 """
c4372a0b
MF
118 indent = ' ' * depth
119 def w(msg, indent=indent, color=None):
120 for line in msg.splitlines():
121 if color:
122 line = self.C(line, color)
123 self.out.write('%s%s\n' % (indent, line))
124 def d(obj, **kwargs):
125 try:
126 self.dump(obj, depth=depth + 1, **kwargs)
127 except Exception as e:
128 w(' <error probing>: %s' % (e,), color=self.RED)
129 raise
130
131 if ((not self.show_std and isinstance(obj, self.TYPES_STANDARD)) or
132 isinstance(obj, self.TYPES_SCALAR)):
133 w('%s: %s' % (self.C(name, self.BOLD), obj), indent=indent[:-2])
134 return
135
136 try:
137 if obj in self.seen:
138 w('%s: %s' % (self.C(name, self.BOLD),
139 self.C('<loop>', self.RED)), indent=indent[:-2])
140 return
141 self.seen.add(obj)
142 except TypeError:
143 pass
144
145 if name:
146 w('%s' % (name,), color=self.BOLD, indent=indent[:-2])
147
148 objr = repr(obj)
149 objs = str(obj)
150 if objr == objs:
151 w('%s: %s' % (type(obj), self.trunc(objs),))
152 else:
153 w('Object.type: %s' % (type(obj),))
154 w(' .repr: %s' % (self.trunc(objr),))
155 w(' .str : %s' % (self.trunc(objs),))
156
157 if depth > self.depth:
158 w('<stop; depth limit hit at %i>' % (depth,), color=self.RED)
159 return
160
161 if isinstance(obj, self.TYPES_ITERABLES):
162 # Iterable types.
163 for i, o in enumerate(obj):
164 d(o, name='[%i]' % (i,))
165 elif isinstance(obj, self.TYPES_SCALAR):
166 # Scalar types; already shown above.
167 pass
168 elif isinstance(obj, self.TYPES_DICT):
169 # Dictionary types.
170 for k, v in obj.items():
171 d(v, name='{%r}' % (k,))
172 elif isinstance(obj, self.TYPES_STANDARD):
173 # Standard types; already shown above.
174 pass
175 elif isinstance(obj, self.TYPES_CALLABLE):
176 # Callable functions.
177 doc = getattr(obj, 'func_doc', None)
178 if doc:
179 w('"""%s"""' % (doc.strip(),), indent=indent + ' ',
180 color=self.BLUE)
181 else:
182 # Unknown type; probe it!
183 doc = getattr(obj, '__doc__', None)
184 if doc:
185 w('"""%s"""' % (doc.strip(),), indent=indent + ' ',
186 color=self.BLUE)
187
188 for k, v in getattr(obj, '__dict__', {}).items():
189 d(v, name='{%r}' % (k,))
190
191 for k in dir(obj):
192 try:
193 s = self.trunc(repr(getattr(obj, k)))
194 except Exception as e:
195 w(' %s: %s' % (self.C(k, self.BOLD),
196 self.C('<error> %s' % str(e), self.RED)))
197 continue
198
199 if k.startswith('__'):
200 if self.show_all or not k.endswith('__'):
201 w(' %s (skipping): %s' % (self.C(k, self.BOLD), s))
202 elif self.show_internal or not k.startswith('_'):
203 d(getattr(obj, k), name=k)
204
205
206def dump(*args, **kwargs):
207 d = Dump(*args, **kwargs)
208 del d
22072cde 209dump.__doc__ = Dump.dump.__doc__