##// END OF EJS Templates
Checks for metaclass's __repr__ in _type_pprint...
Remi Rampin -
Show More
@@ -1,813 +1,819 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 Python advanced pretty printer. This pretty printer is intended to
3 Python advanced pretty printer. This pretty printer is intended to
4 replace the old `pprint` python module which does not allow developers
4 replace the old `pprint` python module which does not allow developers
5 to provide their own pretty print callbacks.
5 to provide their own pretty print callbacks.
6
6
7 This module is based on ruby's `prettyprint.rb` library by `Tanaka Akira`.
7 This module is based on ruby's `prettyprint.rb` library by `Tanaka Akira`.
8
8
9
9
10 Example Usage
10 Example Usage
11 -------------
11 -------------
12
12
13 To directly print the representation of an object use `pprint`::
13 To directly print the representation of an object use `pprint`::
14
14
15 from pretty import pprint
15 from pretty import pprint
16 pprint(complex_object)
16 pprint(complex_object)
17
17
18 To get a string of the output use `pretty`::
18 To get a string of the output use `pretty`::
19
19
20 from pretty import pretty
20 from pretty import pretty
21 string = pretty(complex_object)
21 string = pretty(complex_object)
22
22
23
23
24 Extending
24 Extending
25 ---------
25 ---------
26
26
27 The pretty library allows developers to add pretty printing rules for their
27 The pretty library allows developers to add pretty printing rules for their
28 own objects. This process is straightforward. All you have to do is to
28 own objects. This process is straightforward. All you have to do is to
29 add a `_repr_pretty_` method to your object and call the methods on the
29 add a `_repr_pretty_` method to your object and call the methods on the
30 pretty printer passed::
30 pretty printer passed::
31
31
32 class MyObject(object):
32 class MyObject(object):
33
33
34 def _repr_pretty_(self, p, cycle):
34 def _repr_pretty_(self, p, cycle):
35 ...
35 ...
36
36
37 Depending on the python version you want to support you have two
37 Depending on the python version you want to support you have two
38 possibilities. The following list shows the python 2.5 version and the
38 possibilities. The following list shows the python 2.5 version and the
39 compatibility one.
39 compatibility one.
40
40
41
41
42 Here the example implementation of a `_repr_pretty_` method for a list
42 Here the example implementation of a `_repr_pretty_` method for a list
43 subclass for python 2.5 and higher (python 2.5 requires the with statement
43 subclass for python 2.5 and higher (python 2.5 requires the with statement
44 __future__ import)::
44 __future__ import)::
45
45
46 class MyList(list):
46 class MyList(list):
47
47
48 def _repr_pretty_(self, p, cycle):
48 def _repr_pretty_(self, p, cycle):
49 if cycle:
49 if cycle:
50 p.text('MyList(...)')
50 p.text('MyList(...)')
51 else:
51 else:
52 with p.group(8, 'MyList([', '])'):
52 with p.group(8, 'MyList([', '])'):
53 for idx, item in enumerate(self):
53 for idx, item in enumerate(self):
54 if idx:
54 if idx:
55 p.text(',')
55 p.text(',')
56 p.breakable()
56 p.breakable()
57 p.pretty(item)
57 p.pretty(item)
58
58
59 The `cycle` parameter is `True` if pretty detected a cycle. You *have* to
59 The `cycle` parameter is `True` if pretty detected a cycle. You *have* to
60 react to that or the result is an infinite loop. `p.text()` just adds
60 react to that or the result is an infinite loop. `p.text()` just adds
61 non breaking text to the output, `p.breakable()` either adds a whitespace
61 non breaking text to the output, `p.breakable()` either adds a whitespace
62 or breaks here. If you pass it an argument it's used instead of the
62 or breaks here. If you pass it an argument it's used instead of the
63 default space. `p.pretty` prettyprints another object using the pretty print
63 default space. `p.pretty` prettyprints another object using the pretty print
64 method.
64 method.
65
65
66 The first parameter to the `group` function specifies the extra indentation
66 The first parameter to the `group` function specifies the extra indentation
67 of the next line. In this example the next item will either be not
67 of the next line. In this example the next item will either be not
68 breaked (if the items are short enough) or aligned with the right edge of
68 breaked (if the items are short enough) or aligned with the right edge of
69 the opening bracked of `MyList`.
69 the opening bracked of `MyList`.
70
70
71 If you want to support python 2.4 and lower you can use this code::
71 If you want to support python 2.4 and lower you can use this code::
72
72
73 class MyList(list):
73 class MyList(list):
74
74
75 def _repr_pretty_(self, p, cycle):
75 def _repr_pretty_(self, p, cycle):
76 if cycle:
76 if cycle:
77 p.text('MyList(...)')
77 p.text('MyList(...)')
78 else:
78 else:
79 p.begin_group(8, 'MyList([')
79 p.begin_group(8, 'MyList([')
80 for idx, item in enumerate(self):
80 for idx, item in enumerate(self):
81 if idx:
81 if idx:
82 p.text(',')
82 p.text(',')
83 p.breakable()
83 p.breakable()
84 p.pretty(item)
84 p.pretty(item)
85 p.end_group(8, '])')
85 p.end_group(8, '])')
86
86
87 If you just want to indent something you can use the group function
87 If you just want to indent something you can use the group function
88 without open / close parameters. Under python 2.5 you can also use this
88 without open / close parameters. Under python 2.5 you can also use this
89 code::
89 code::
90
90
91 with p.indent(2):
91 with p.indent(2):
92 ...
92 ...
93
93
94 Or under python2.4 you might want to modify ``p.indentation`` by hand but
94 Or under python2.4 you might want to modify ``p.indentation`` by hand but
95 this is rather ugly.
95 this is rather ugly.
96
96
97 Inheritance diagram:
97 Inheritance diagram:
98
98
99 .. inheritance-diagram:: IPython.lib.pretty
99 .. inheritance-diagram:: IPython.lib.pretty
100 :parts: 3
100 :parts: 3
101
101
102 :copyright: 2007 by Armin Ronacher.
102 :copyright: 2007 by Armin Ronacher.
103 Portions (c) 2009 by Robert Kern.
103 Portions (c) 2009 by Robert Kern.
104 :license: BSD License.
104 :license: BSD License.
105 """
105 """
106 from __future__ import print_function
106 from __future__ import print_function
107 from contextlib import contextmanager
107 from contextlib import contextmanager
108 import sys
108 import sys
109 import types
109 import types
110 import re
110 import re
111 import datetime
111 import datetime
112 from collections import deque
112 from collections import deque
113
113
114 from IPython.utils.py3compat import PY3
114 from IPython.utils.py3compat import PY3
115
115
116 if PY3:
116 if PY3:
117 from io import StringIO
117 from io import StringIO
118 else:
118 else:
119 from StringIO import StringIO
119 from StringIO import StringIO
120
120
121
121
122 __all__ = ['pretty', 'pprint', 'PrettyPrinter', 'RepresentationPrinter',
122 __all__ = ['pretty', 'pprint', 'PrettyPrinter', 'RepresentationPrinter',
123 'for_type', 'for_type_by_name']
123 'for_type', 'for_type_by_name']
124
124
125
125
126 _re_pattern_type = type(re.compile(''))
126 _re_pattern_type = type(re.compile(''))
127
127
128
128
129 def _safe_getattr(obj, attr, default=None):
129 def _safe_getattr(obj, attr, default=None):
130 """Safe version of getattr.
130 """Safe version of getattr.
131
131
132 Same as getattr, but will return ``default`` on any Exception,
132 Same as getattr, but will return ``default`` on any Exception,
133 rather than raising.
133 rather than raising.
134 """
134 """
135 try:
135 try:
136 return getattr(obj, attr, default)
136 return getattr(obj, attr, default)
137 except Exception:
137 except Exception:
138 return default
138 return default
139
139
140 def pretty(obj, verbose=False, max_width=79, newline='\n'):
140 def pretty(obj, verbose=False, max_width=79, newline='\n'):
141 """
141 """
142 Pretty print the object's representation.
142 Pretty print the object's representation.
143 """
143 """
144 stream = StringIO()
144 stream = StringIO()
145 printer = RepresentationPrinter(stream, verbose, max_width, newline)
145 printer = RepresentationPrinter(stream, verbose, max_width, newline)
146 printer.pretty(obj)
146 printer.pretty(obj)
147 printer.flush()
147 printer.flush()
148 return stream.getvalue()
148 return stream.getvalue()
149
149
150
150
151 def pprint(obj, verbose=False, max_width=79, newline='\n'):
151 def pprint(obj, verbose=False, max_width=79, newline='\n'):
152 """
152 """
153 Like `pretty` but print to stdout.
153 Like `pretty` but print to stdout.
154 """
154 """
155 printer = RepresentationPrinter(sys.stdout, verbose, max_width, newline)
155 printer = RepresentationPrinter(sys.stdout, verbose, max_width, newline)
156 printer.pretty(obj)
156 printer.pretty(obj)
157 printer.flush()
157 printer.flush()
158 sys.stdout.write(newline)
158 sys.stdout.write(newline)
159 sys.stdout.flush()
159 sys.stdout.flush()
160
160
161 class _PrettyPrinterBase(object):
161 class _PrettyPrinterBase(object):
162
162
163 @contextmanager
163 @contextmanager
164 def indent(self, indent):
164 def indent(self, indent):
165 """with statement support for indenting/dedenting."""
165 """with statement support for indenting/dedenting."""
166 self.indentation += indent
166 self.indentation += indent
167 try:
167 try:
168 yield
168 yield
169 finally:
169 finally:
170 self.indentation -= indent
170 self.indentation -= indent
171
171
172 @contextmanager
172 @contextmanager
173 def group(self, indent=0, open='', close=''):
173 def group(self, indent=0, open='', close=''):
174 """like begin_group / end_group but for the with statement."""
174 """like begin_group / end_group but for the with statement."""
175 self.begin_group(indent, open)
175 self.begin_group(indent, open)
176 try:
176 try:
177 yield
177 yield
178 finally:
178 finally:
179 self.end_group(indent, close)
179 self.end_group(indent, close)
180
180
181 class PrettyPrinter(_PrettyPrinterBase):
181 class PrettyPrinter(_PrettyPrinterBase):
182 """
182 """
183 Baseclass for the `RepresentationPrinter` prettyprinter that is used to
183 Baseclass for the `RepresentationPrinter` prettyprinter that is used to
184 generate pretty reprs of objects. Contrary to the `RepresentationPrinter`
184 generate pretty reprs of objects. Contrary to the `RepresentationPrinter`
185 this printer knows nothing about the default pprinters or the `_repr_pretty_`
185 this printer knows nothing about the default pprinters or the `_repr_pretty_`
186 callback method.
186 callback method.
187 """
187 """
188
188
189 def __init__(self, output, max_width=79, newline='\n', max_seq_length=1000):
189 def __init__(self, output, max_width=79, newline='\n', max_seq_length=1000):
190 self.output = output
190 self.output = output
191 self.max_width = max_width
191 self.max_width = max_width
192 self.newline = newline
192 self.newline = newline
193 self.max_seq_length = max_seq_length
193 self.max_seq_length = max_seq_length
194 self.output_width = 0
194 self.output_width = 0
195 self.buffer_width = 0
195 self.buffer_width = 0
196 self.buffer = deque()
196 self.buffer = deque()
197
197
198 root_group = Group(0)
198 root_group = Group(0)
199 self.group_stack = [root_group]
199 self.group_stack = [root_group]
200 self.group_queue = GroupQueue(root_group)
200 self.group_queue = GroupQueue(root_group)
201 self.indentation = 0
201 self.indentation = 0
202
202
203 def _break_outer_groups(self):
203 def _break_outer_groups(self):
204 while self.max_width < self.output_width + self.buffer_width:
204 while self.max_width < self.output_width + self.buffer_width:
205 group = self.group_queue.deq()
205 group = self.group_queue.deq()
206 if not group:
206 if not group:
207 return
207 return
208 while group.breakables:
208 while group.breakables:
209 x = self.buffer.popleft()
209 x = self.buffer.popleft()
210 self.output_width = x.output(self.output, self.output_width)
210 self.output_width = x.output(self.output, self.output_width)
211 self.buffer_width -= x.width
211 self.buffer_width -= x.width
212 while self.buffer and isinstance(self.buffer[0], Text):
212 while self.buffer and isinstance(self.buffer[0], Text):
213 x = self.buffer.popleft()
213 x = self.buffer.popleft()
214 self.output_width = x.output(self.output, self.output_width)
214 self.output_width = x.output(self.output, self.output_width)
215 self.buffer_width -= x.width
215 self.buffer_width -= x.width
216
216
217 def text(self, obj):
217 def text(self, obj):
218 """Add literal text to the output."""
218 """Add literal text to the output."""
219 width = len(obj)
219 width = len(obj)
220 if self.buffer:
220 if self.buffer:
221 text = self.buffer[-1]
221 text = self.buffer[-1]
222 if not isinstance(text, Text):
222 if not isinstance(text, Text):
223 text = Text()
223 text = Text()
224 self.buffer.append(text)
224 self.buffer.append(text)
225 text.add(obj, width)
225 text.add(obj, width)
226 self.buffer_width += width
226 self.buffer_width += width
227 self._break_outer_groups()
227 self._break_outer_groups()
228 else:
228 else:
229 self.output.write(obj)
229 self.output.write(obj)
230 self.output_width += width
230 self.output_width += width
231
231
232 def breakable(self, sep=' '):
232 def breakable(self, sep=' '):
233 """
233 """
234 Add a breakable separator to the output. This does not mean that it
234 Add a breakable separator to the output. This does not mean that it
235 will automatically break here. If no breaking on this position takes
235 will automatically break here. If no breaking on this position takes
236 place the `sep` is inserted which default to one space.
236 place the `sep` is inserted which default to one space.
237 """
237 """
238 width = len(sep)
238 width = len(sep)
239 group = self.group_stack[-1]
239 group = self.group_stack[-1]
240 if group.want_break:
240 if group.want_break:
241 self.flush()
241 self.flush()
242 self.output.write(self.newline)
242 self.output.write(self.newline)
243 self.output.write(' ' * self.indentation)
243 self.output.write(' ' * self.indentation)
244 self.output_width = self.indentation
244 self.output_width = self.indentation
245 self.buffer_width = 0
245 self.buffer_width = 0
246 else:
246 else:
247 self.buffer.append(Breakable(sep, width, self))
247 self.buffer.append(Breakable(sep, width, self))
248 self.buffer_width += width
248 self.buffer_width += width
249 self._break_outer_groups()
249 self._break_outer_groups()
250
250
251 def break_(self):
251 def break_(self):
252 """
252 """
253 Explicitly insert a newline into the output, maintaining correct indentation.
253 Explicitly insert a newline into the output, maintaining correct indentation.
254 """
254 """
255 self.flush()
255 self.flush()
256 self.output.write(self.newline)
256 self.output.write(self.newline)
257 self.output.write(' ' * self.indentation)
257 self.output.write(' ' * self.indentation)
258 self.output_width = self.indentation
258 self.output_width = self.indentation
259 self.buffer_width = 0
259 self.buffer_width = 0
260
260
261
261
262 def begin_group(self, indent=0, open=''):
262 def begin_group(self, indent=0, open=''):
263 """
263 """
264 Begin a group. If you want support for python < 2.5 which doesn't has
264 Begin a group. If you want support for python < 2.5 which doesn't has
265 the with statement this is the preferred way:
265 the with statement this is the preferred way:
266
266
267 p.begin_group(1, '{')
267 p.begin_group(1, '{')
268 ...
268 ...
269 p.end_group(1, '}')
269 p.end_group(1, '}')
270
270
271 The python 2.5 expression would be this:
271 The python 2.5 expression would be this:
272
272
273 with p.group(1, '{', '}'):
273 with p.group(1, '{', '}'):
274 ...
274 ...
275
275
276 The first parameter specifies the indentation for the next line (usually
276 The first parameter specifies the indentation for the next line (usually
277 the width of the opening text), the second the opening text. All
277 the width of the opening text), the second the opening text. All
278 parameters are optional.
278 parameters are optional.
279 """
279 """
280 if open:
280 if open:
281 self.text(open)
281 self.text(open)
282 group = Group(self.group_stack[-1].depth + 1)
282 group = Group(self.group_stack[-1].depth + 1)
283 self.group_stack.append(group)
283 self.group_stack.append(group)
284 self.group_queue.enq(group)
284 self.group_queue.enq(group)
285 self.indentation += indent
285 self.indentation += indent
286
286
287 def _enumerate(self, seq):
287 def _enumerate(self, seq):
288 """like enumerate, but with an upper limit on the number of items"""
288 """like enumerate, but with an upper limit on the number of items"""
289 for idx, x in enumerate(seq):
289 for idx, x in enumerate(seq):
290 if self.max_seq_length and idx >= self.max_seq_length:
290 if self.max_seq_length and idx >= self.max_seq_length:
291 self.text(',')
291 self.text(',')
292 self.breakable()
292 self.breakable()
293 self.text('...')
293 self.text('...')
294 raise StopIteration
294 raise StopIteration
295 yield idx, x
295 yield idx, x
296
296
297 def end_group(self, dedent=0, close=''):
297 def end_group(self, dedent=0, close=''):
298 """End a group. See `begin_group` for more details."""
298 """End a group. See `begin_group` for more details."""
299 self.indentation -= dedent
299 self.indentation -= dedent
300 group = self.group_stack.pop()
300 group = self.group_stack.pop()
301 if not group.breakables:
301 if not group.breakables:
302 self.group_queue.remove(group)
302 self.group_queue.remove(group)
303 if close:
303 if close:
304 self.text(close)
304 self.text(close)
305
305
306 def flush(self):
306 def flush(self):
307 """Flush data that is left in the buffer."""
307 """Flush data that is left in the buffer."""
308 for data in self.buffer:
308 for data in self.buffer:
309 self.output_width += data.output(self.output, self.output_width)
309 self.output_width += data.output(self.output, self.output_width)
310 self.buffer.clear()
310 self.buffer.clear()
311 self.buffer_width = 0
311 self.buffer_width = 0
312
312
313
313
314 def _get_mro(obj_class):
314 def _get_mro(obj_class):
315 """ Get a reasonable method resolution order of a class and its superclasses
315 """ Get a reasonable method resolution order of a class and its superclasses
316 for both old-style and new-style classes.
316 for both old-style and new-style classes.
317 """
317 """
318 if not hasattr(obj_class, '__mro__'):
318 if not hasattr(obj_class, '__mro__'):
319 # Old-style class. Mix in object to make a fake new-style class.
319 # Old-style class. Mix in object to make a fake new-style class.
320 try:
320 try:
321 obj_class = type(obj_class.__name__, (obj_class, object), {})
321 obj_class = type(obj_class.__name__, (obj_class, object), {})
322 except TypeError:
322 except TypeError:
323 # Old-style extension type that does not descend from object.
323 # Old-style extension type that does not descend from object.
324 # FIXME: try to construct a more thorough MRO.
324 # FIXME: try to construct a more thorough MRO.
325 mro = [obj_class]
325 mro = [obj_class]
326 else:
326 else:
327 mro = obj_class.__mro__[1:-1]
327 mro = obj_class.__mro__[1:-1]
328 else:
328 else:
329 mro = obj_class.__mro__
329 mro = obj_class.__mro__
330 return mro
330 return mro
331
331
332
332
333 class RepresentationPrinter(PrettyPrinter):
333 class RepresentationPrinter(PrettyPrinter):
334 """
334 """
335 Special pretty printer that has a `pretty` method that calls the pretty
335 Special pretty printer that has a `pretty` method that calls the pretty
336 printer for a python object.
336 printer for a python object.
337
337
338 This class stores processing data on `self` so you must *never* use
338 This class stores processing data on `self` so you must *never* use
339 this class in a threaded environment. Always lock it or reinstanciate
339 this class in a threaded environment. Always lock it or reinstanciate
340 it.
340 it.
341
341
342 Instances also have a verbose flag callbacks can access to control their
342 Instances also have a verbose flag callbacks can access to control their
343 output. For example the default instance repr prints all attributes and
343 output. For example the default instance repr prints all attributes and
344 methods that are not prefixed by an underscore if the printer is in
344 methods that are not prefixed by an underscore if the printer is in
345 verbose mode.
345 verbose mode.
346 """
346 """
347
347
348 def __init__(self, output, verbose=False, max_width=79, newline='\n',
348 def __init__(self, output, verbose=False, max_width=79, newline='\n',
349 singleton_pprinters=None, type_pprinters=None, deferred_pprinters=None):
349 singleton_pprinters=None, type_pprinters=None, deferred_pprinters=None):
350
350
351 PrettyPrinter.__init__(self, output, max_width, newline)
351 PrettyPrinter.__init__(self, output, max_width, newline)
352 self.verbose = verbose
352 self.verbose = verbose
353 self.stack = []
353 self.stack = []
354 if singleton_pprinters is None:
354 if singleton_pprinters is None:
355 singleton_pprinters = _singleton_pprinters.copy()
355 singleton_pprinters = _singleton_pprinters.copy()
356 self.singleton_pprinters = singleton_pprinters
356 self.singleton_pprinters = singleton_pprinters
357 if type_pprinters is None:
357 if type_pprinters is None:
358 type_pprinters = _type_pprinters.copy()
358 type_pprinters = _type_pprinters.copy()
359 self.type_pprinters = type_pprinters
359 self.type_pprinters = type_pprinters
360 if deferred_pprinters is None:
360 if deferred_pprinters is None:
361 deferred_pprinters = _deferred_type_pprinters.copy()
361 deferred_pprinters = _deferred_type_pprinters.copy()
362 self.deferred_pprinters = deferred_pprinters
362 self.deferred_pprinters = deferred_pprinters
363
363
364 def pretty(self, obj):
364 def pretty(self, obj):
365 """Pretty print the given object."""
365 """Pretty print the given object."""
366 obj_id = id(obj)
366 obj_id = id(obj)
367 cycle = obj_id in self.stack
367 cycle = obj_id in self.stack
368 self.stack.append(obj_id)
368 self.stack.append(obj_id)
369 self.begin_group()
369 self.begin_group()
370 try:
370 try:
371 obj_class = _safe_getattr(obj, '__class__', None) or type(obj)
371 obj_class = _safe_getattr(obj, '__class__', None) or type(obj)
372 # First try to find registered singleton printers for the type.
372 # First try to find registered singleton printers for the type.
373 try:
373 try:
374 printer = self.singleton_pprinters[obj_id]
374 printer = self.singleton_pprinters[obj_id]
375 except (TypeError, KeyError):
375 except (TypeError, KeyError):
376 pass
376 pass
377 else:
377 else:
378 return printer(obj, self, cycle)
378 return printer(obj, self, cycle)
379 # Next walk the mro and check for either:
379 # Next walk the mro and check for either:
380 # 1) a registered printer
380 # 1) a registered printer
381 # 2) a _repr_pretty_ method
381 # 2) a _repr_pretty_ method
382 for cls in _get_mro(obj_class):
382 for cls in _get_mro(obj_class):
383 if cls in self.type_pprinters:
383 if cls in self.type_pprinters:
384 # printer registered in self.type_pprinters
384 # printer registered in self.type_pprinters
385 return self.type_pprinters[cls](obj, self, cycle)
385 return self.type_pprinters[cls](obj, self, cycle)
386 else:
386 else:
387 # deferred printer
387 # deferred printer
388 printer = self._in_deferred_types(cls)
388 printer = self._in_deferred_types(cls)
389 if printer is not None:
389 if printer is not None:
390 return printer(obj, self, cycle)
390 return printer(obj, self, cycle)
391 else:
391 else:
392 # Finally look for special method names.
392 # Finally look for special method names.
393 # Some objects automatically create any requested
393 # Some objects automatically create any requested
394 # attribute. Try to ignore most of them by checking for
394 # attribute. Try to ignore most of them by checking for
395 # callability.
395 # callability.
396 if '_repr_pretty_' in cls.__dict__:
396 if '_repr_pretty_' in cls.__dict__:
397 meth = cls._repr_pretty_
397 meth = cls._repr_pretty_
398 if callable(meth):
398 if callable(meth):
399 return meth(obj, self, cycle)
399 return meth(obj, self, cycle)
400 return _default_pprint(obj, self, cycle)
400 return _default_pprint(obj, self, cycle)
401 finally:
401 finally:
402 self.end_group()
402 self.end_group()
403 self.stack.pop()
403 self.stack.pop()
404
404
405 def _in_deferred_types(self, cls):
405 def _in_deferred_types(self, cls):
406 """
406 """
407 Check if the given class is specified in the deferred type registry.
407 Check if the given class is specified in the deferred type registry.
408
408
409 Returns the printer from the registry if it exists, and None if the
409 Returns the printer from the registry if it exists, and None if the
410 class is not in the registry. Successful matches will be moved to the
410 class is not in the registry. Successful matches will be moved to the
411 regular type registry for future use.
411 regular type registry for future use.
412 """
412 """
413 mod = _safe_getattr(cls, '__module__', None)
413 mod = _safe_getattr(cls, '__module__', None)
414 name = _safe_getattr(cls, '__name__', None)
414 name = _safe_getattr(cls, '__name__', None)
415 key = (mod, name)
415 key = (mod, name)
416 printer = None
416 printer = None
417 if key in self.deferred_pprinters:
417 if key in self.deferred_pprinters:
418 # Move the printer over to the regular registry.
418 # Move the printer over to the regular registry.
419 printer = self.deferred_pprinters.pop(key)
419 printer = self.deferred_pprinters.pop(key)
420 self.type_pprinters[cls] = printer
420 self.type_pprinters[cls] = printer
421 return printer
421 return printer
422
422
423
423
424 class Printable(object):
424 class Printable(object):
425
425
426 def output(self, stream, output_width):
426 def output(self, stream, output_width):
427 return output_width
427 return output_width
428
428
429
429
430 class Text(Printable):
430 class Text(Printable):
431
431
432 def __init__(self):
432 def __init__(self):
433 self.objs = []
433 self.objs = []
434 self.width = 0
434 self.width = 0
435
435
436 def output(self, stream, output_width):
436 def output(self, stream, output_width):
437 for obj in self.objs:
437 for obj in self.objs:
438 stream.write(obj)
438 stream.write(obj)
439 return output_width + self.width
439 return output_width + self.width
440
440
441 def add(self, obj, width):
441 def add(self, obj, width):
442 self.objs.append(obj)
442 self.objs.append(obj)
443 self.width += width
443 self.width += width
444
444
445
445
446 class Breakable(Printable):
446 class Breakable(Printable):
447
447
448 def __init__(self, seq, width, pretty):
448 def __init__(self, seq, width, pretty):
449 self.obj = seq
449 self.obj = seq
450 self.width = width
450 self.width = width
451 self.pretty = pretty
451 self.pretty = pretty
452 self.indentation = pretty.indentation
452 self.indentation = pretty.indentation
453 self.group = pretty.group_stack[-1]
453 self.group = pretty.group_stack[-1]
454 self.group.breakables.append(self)
454 self.group.breakables.append(self)
455
455
456 def output(self, stream, output_width):
456 def output(self, stream, output_width):
457 self.group.breakables.popleft()
457 self.group.breakables.popleft()
458 if self.group.want_break:
458 if self.group.want_break:
459 stream.write(self.pretty.newline)
459 stream.write(self.pretty.newline)
460 stream.write(' ' * self.indentation)
460 stream.write(' ' * self.indentation)
461 return self.indentation
461 return self.indentation
462 if not self.group.breakables:
462 if not self.group.breakables:
463 self.pretty.group_queue.remove(self.group)
463 self.pretty.group_queue.remove(self.group)
464 stream.write(self.obj)
464 stream.write(self.obj)
465 return output_width + self.width
465 return output_width + self.width
466
466
467
467
468 class Group(Printable):
468 class Group(Printable):
469
469
470 def __init__(self, depth):
470 def __init__(self, depth):
471 self.depth = depth
471 self.depth = depth
472 self.breakables = deque()
472 self.breakables = deque()
473 self.want_break = False
473 self.want_break = False
474
474
475
475
476 class GroupQueue(object):
476 class GroupQueue(object):
477
477
478 def __init__(self, *groups):
478 def __init__(self, *groups):
479 self.queue = []
479 self.queue = []
480 for group in groups:
480 for group in groups:
481 self.enq(group)
481 self.enq(group)
482
482
483 def enq(self, group):
483 def enq(self, group):
484 depth = group.depth
484 depth = group.depth
485 while depth > len(self.queue) - 1:
485 while depth > len(self.queue) - 1:
486 self.queue.append([])
486 self.queue.append([])
487 self.queue[depth].append(group)
487 self.queue[depth].append(group)
488
488
489 def deq(self):
489 def deq(self):
490 for stack in self.queue:
490 for stack in self.queue:
491 for idx, group in enumerate(reversed(stack)):
491 for idx, group in enumerate(reversed(stack)):
492 if group.breakables:
492 if group.breakables:
493 del stack[idx]
493 del stack[idx]
494 group.want_break = True
494 group.want_break = True
495 return group
495 return group
496 for group in stack:
496 for group in stack:
497 group.want_break = True
497 group.want_break = True
498 del stack[:]
498 del stack[:]
499
499
500 def remove(self, group):
500 def remove(self, group):
501 try:
501 try:
502 self.queue[group.depth].remove(group)
502 self.queue[group.depth].remove(group)
503 except ValueError:
503 except ValueError:
504 pass
504 pass
505
505
506 try:
506 try:
507 _baseclass_reprs = (object.__repr__, types.InstanceType.__repr__)
507 _baseclass_reprs = (object.__repr__, types.InstanceType.__repr__)
508 except AttributeError: # Python 3
508 except AttributeError: # Python 3
509 _baseclass_reprs = (object.__repr__,)
509 _baseclass_reprs = (object.__repr__,)
510
510
511
511
512 def _default_pprint(obj, p, cycle):
512 def _default_pprint(obj, p, cycle):
513 """
513 """
514 The default print function. Used if an object does not provide one and
514 The default print function. Used if an object does not provide one and
515 it's none of the builtin objects.
515 it's none of the builtin objects.
516 """
516 """
517 klass = _safe_getattr(obj, '__class__', None) or type(obj)
517 klass = _safe_getattr(obj, '__class__', None) or type(obj)
518 if _safe_getattr(klass, '__repr__', None) not in _baseclass_reprs:
518 if _safe_getattr(klass, '__repr__', None) not in _baseclass_reprs:
519 # A user-provided repr. Find newlines and replace them with p.break_()
519 # A user-provided repr. Find newlines and replace them with p.break_()
520 output = repr(obj)
520 output = repr(obj)
521 for idx,output_line in enumerate(output.splitlines()):
521 for idx,output_line in enumerate(output.splitlines()):
522 if idx:
522 if idx:
523 p.break_()
523 p.break_()
524 p.text(output_line)
524 p.text(output_line)
525 return
525 return
526 p.begin_group(1, '<')
526 p.begin_group(1, '<')
527 p.pretty(klass)
527 p.pretty(klass)
528 p.text(' at 0x%x' % id(obj))
528 p.text(' at 0x%x' % id(obj))
529 if cycle:
529 if cycle:
530 p.text(' ...')
530 p.text(' ...')
531 elif p.verbose:
531 elif p.verbose:
532 first = True
532 first = True
533 for key in dir(obj):
533 for key in dir(obj):
534 if not key.startswith('_'):
534 if not key.startswith('_'):
535 try:
535 try:
536 value = getattr(obj, key)
536 value = getattr(obj, key)
537 except AttributeError:
537 except AttributeError:
538 continue
538 continue
539 if isinstance(value, types.MethodType):
539 if isinstance(value, types.MethodType):
540 continue
540 continue
541 if not first:
541 if not first:
542 p.text(',')
542 p.text(',')
543 p.breakable()
543 p.breakable()
544 p.text(key)
544 p.text(key)
545 p.text('=')
545 p.text('=')
546 step = len(key) + 1
546 step = len(key) + 1
547 p.indentation += step
547 p.indentation += step
548 p.pretty(value)
548 p.pretty(value)
549 p.indentation -= step
549 p.indentation -= step
550 first = False
550 first = False
551 p.end_group(1, '>')
551 p.end_group(1, '>')
552
552
553
553
554 def _seq_pprinter_factory(start, end, basetype):
554 def _seq_pprinter_factory(start, end, basetype):
555 """
555 """
556 Factory that returns a pprint function useful for sequences. Used by
556 Factory that returns a pprint function useful for sequences. Used by
557 the default pprint for tuples, dicts, and lists.
557 the default pprint for tuples, dicts, and lists.
558 """
558 """
559 def inner(obj, p, cycle):
559 def inner(obj, p, cycle):
560 typ = type(obj)
560 typ = type(obj)
561 if basetype is not None and typ is not basetype and typ.__repr__ != basetype.__repr__:
561 if basetype is not None and typ is not basetype and typ.__repr__ != basetype.__repr__:
562 # If the subclass provides its own repr, use it instead.
562 # If the subclass provides its own repr, use it instead.
563 return p.text(typ.__repr__(obj))
563 return p.text(typ.__repr__(obj))
564
564
565 if cycle:
565 if cycle:
566 return p.text(start + '...' + end)
566 return p.text(start + '...' + end)
567 step = len(start)
567 step = len(start)
568 p.begin_group(step, start)
568 p.begin_group(step, start)
569 for idx, x in p._enumerate(obj):
569 for idx, x in p._enumerate(obj):
570 if idx:
570 if idx:
571 p.text(',')
571 p.text(',')
572 p.breakable()
572 p.breakable()
573 p.pretty(x)
573 p.pretty(x)
574 if len(obj) == 1 and type(obj) is tuple:
574 if len(obj) == 1 and type(obj) is tuple:
575 # Special case for 1-item tuples.
575 # Special case for 1-item tuples.
576 p.text(',')
576 p.text(',')
577 p.end_group(step, end)
577 p.end_group(step, end)
578 return inner
578 return inner
579
579
580
580
581 def _set_pprinter_factory(start, end, basetype):
581 def _set_pprinter_factory(start, end, basetype):
582 """
582 """
583 Factory that returns a pprint function useful for sets and frozensets.
583 Factory that returns a pprint function useful for sets and frozensets.
584 """
584 """
585 def inner(obj, p, cycle):
585 def inner(obj, p, cycle):
586 typ = type(obj)
586 typ = type(obj)
587 if basetype is not None and typ is not basetype and typ.__repr__ != basetype.__repr__:
587 if basetype is not None and typ is not basetype and typ.__repr__ != basetype.__repr__:
588 # If the subclass provides its own repr, use it instead.
588 # If the subclass provides its own repr, use it instead.
589 return p.text(typ.__repr__(obj))
589 return p.text(typ.__repr__(obj))
590
590
591 if cycle:
591 if cycle:
592 return p.text(start + '...' + end)
592 return p.text(start + '...' + end)
593 if len(obj) == 0:
593 if len(obj) == 0:
594 # Special case.
594 # Special case.
595 p.text(basetype.__name__ + '()')
595 p.text(basetype.__name__ + '()')
596 else:
596 else:
597 step = len(start)
597 step = len(start)
598 p.begin_group(step, start)
598 p.begin_group(step, start)
599 # Like dictionary keys, we will try to sort the items.
599 # Like dictionary keys, we will try to sort the items.
600 items = list(obj)
600 items = list(obj)
601 try:
601 try:
602 items.sort()
602 items.sort()
603 except Exception:
603 except Exception:
604 # Sometimes the items don't sort.
604 # Sometimes the items don't sort.
605 pass
605 pass
606 for idx, x in p._enumerate(items):
606 for idx, x in p._enumerate(items):
607 if idx:
607 if idx:
608 p.text(',')
608 p.text(',')
609 p.breakable()
609 p.breakable()
610 p.pretty(x)
610 p.pretty(x)
611 p.end_group(step, end)
611 p.end_group(step, end)
612 return inner
612 return inner
613
613
614
614
615 def _dict_pprinter_factory(start, end, basetype=None):
615 def _dict_pprinter_factory(start, end, basetype=None):
616 """
616 """
617 Factory that returns a pprint function used by the default pprint of
617 Factory that returns a pprint function used by the default pprint of
618 dicts and dict proxies.
618 dicts and dict proxies.
619 """
619 """
620 def inner(obj, p, cycle):
620 def inner(obj, p, cycle):
621 typ = type(obj)
621 typ = type(obj)
622 if basetype is not None and typ is not basetype and typ.__repr__ != basetype.__repr__:
622 if basetype is not None and typ is not basetype and typ.__repr__ != basetype.__repr__:
623 # If the subclass provides its own repr, use it instead.
623 # If the subclass provides its own repr, use it instead.
624 return p.text(typ.__repr__(obj))
624 return p.text(typ.__repr__(obj))
625
625
626 if cycle:
626 if cycle:
627 return p.text('{...}')
627 return p.text('{...}')
628 p.begin_group(1, start)
628 p.begin_group(1, start)
629 keys = obj.keys()
629 keys = obj.keys()
630 try:
630 try:
631 keys.sort()
631 keys.sort()
632 except Exception as e:
632 except Exception as e:
633 # Sometimes the keys don't sort.
633 # Sometimes the keys don't sort.
634 pass
634 pass
635 for idx, key in p._enumerate(keys):
635 for idx, key in p._enumerate(keys):
636 if idx:
636 if idx:
637 p.text(',')
637 p.text(',')
638 p.breakable()
638 p.breakable()
639 p.pretty(key)
639 p.pretty(key)
640 p.text(': ')
640 p.text(': ')
641 p.pretty(obj[key])
641 p.pretty(obj[key])
642 p.end_group(1, end)
642 p.end_group(1, end)
643 return inner
643 return inner
644
644
645
645
646 def _super_pprint(obj, p, cycle):
646 def _super_pprint(obj, p, cycle):
647 """The pprint for the super type."""
647 """The pprint for the super type."""
648 p.begin_group(8, '<super: ')
648 p.begin_group(8, '<super: ')
649 p.pretty(obj.__thisclass__)
649 p.pretty(obj.__thisclass__)
650 p.text(',')
650 p.text(',')
651 p.breakable()
651 p.breakable()
652 p.pretty(obj.__self__)
652 p.pretty(obj.__self__)
653 p.end_group(8, '>')
653 p.end_group(8, '>')
654
654
655
655
656 def _re_pattern_pprint(obj, p, cycle):
656 def _re_pattern_pprint(obj, p, cycle):
657 """The pprint function for regular expression patterns."""
657 """The pprint function for regular expression patterns."""
658 p.text('re.compile(')
658 p.text('re.compile(')
659 pattern = repr(obj.pattern)
659 pattern = repr(obj.pattern)
660 if pattern[:1] in 'uU':
660 if pattern[:1] in 'uU':
661 pattern = pattern[1:]
661 pattern = pattern[1:]
662 prefix = 'ur'
662 prefix = 'ur'
663 else:
663 else:
664 prefix = 'r'
664 prefix = 'r'
665 pattern = prefix + pattern.replace('\\\\', '\\')
665 pattern = prefix + pattern.replace('\\\\', '\\')
666 p.text(pattern)
666 p.text(pattern)
667 if obj.flags:
667 if obj.flags:
668 p.text(',')
668 p.text(',')
669 p.breakable()
669 p.breakable()
670 done_one = False
670 done_one = False
671 for flag in ('TEMPLATE', 'IGNORECASE', 'LOCALE', 'MULTILINE', 'DOTALL',
671 for flag in ('TEMPLATE', 'IGNORECASE', 'LOCALE', 'MULTILINE', 'DOTALL',
672 'UNICODE', 'VERBOSE', 'DEBUG'):
672 'UNICODE', 'VERBOSE', 'DEBUG'):
673 if obj.flags & getattr(re, flag):
673 if obj.flags & getattr(re, flag):
674 if done_one:
674 if done_one:
675 p.text('|')
675 p.text('|')
676 p.text('re.' + flag)
676 p.text('re.' + flag)
677 done_one = True
677 done_one = True
678 p.text(')')
678 p.text(')')
679
679
680
680
681 def _type_pprint(obj, p, cycle):
681 def _type_pprint(obj, p, cycle):
682 """The pprint for classes and types."""
682 """The pprint for classes and types."""
683 # Heap allocated types might not have the module attribute,
683 # Heap allocated types might not have the module attribute,
684 # and others may set it to None.
684 # and others may set it to None.
685
686 # Checks for a __repr__ override in the metaclass
687 if type(obj).__repr__ is not type.__repr__:
688 p.text(repr(obj))
689 return
690
685 mod = _safe_getattr(obj, '__module__', None)
691 mod = _safe_getattr(obj, '__module__', None)
686 name = _safe_getattr(obj, '__qualname__', obj.__name__)
692 name = _safe_getattr(obj, '__qualname__', obj.__name__)
687
693
688 if mod in (None, '__builtin__', 'builtins', 'exceptions'):
694 if mod in (None, '__builtin__', 'builtins', 'exceptions'):
689 p.text(name)
695 p.text(name)
690 else:
696 else:
691 p.text(mod + '.' + name)
697 p.text(mod + '.' + name)
692
698
693
699
694 def _repr_pprint(obj, p, cycle):
700 def _repr_pprint(obj, p, cycle):
695 """A pprint that just redirects to the normal repr function."""
701 """A pprint that just redirects to the normal repr function."""
696 p.text(repr(obj))
702 p.text(repr(obj))
697
703
698
704
699 def _function_pprint(obj, p, cycle):
705 def _function_pprint(obj, p, cycle):
700 """Base pprint for all functions and builtin functions."""
706 """Base pprint for all functions and builtin functions."""
701 name = _safe_getattr(obj, '__qualname__', obj.__name__)
707 name = _safe_getattr(obj, '__qualname__', obj.__name__)
702 mod = obj.__module__
708 mod = obj.__module__
703 if mod and mod not in ('__builtin__', 'builtins', 'exceptions'):
709 if mod and mod not in ('__builtin__', 'builtins', 'exceptions'):
704 name = mod + '.' + name
710 name = mod + '.' + name
705 p.text('<function %s>' % name)
711 p.text('<function %s>' % name)
706
712
707
713
708 def _exception_pprint(obj, p, cycle):
714 def _exception_pprint(obj, p, cycle):
709 """Base pprint for all exceptions."""
715 """Base pprint for all exceptions."""
710 name = getattr(obj.__class__, '__qualname__', obj.__class__.__name__)
716 name = getattr(obj.__class__, '__qualname__', obj.__class__.__name__)
711 if obj.__class__.__module__ not in ('exceptions', 'builtins'):
717 if obj.__class__.__module__ not in ('exceptions', 'builtins'):
712 name = '%s.%s' % (obj.__class__.__module__, name)
718 name = '%s.%s' % (obj.__class__.__module__, name)
713 step = len(name) + 1
719 step = len(name) + 1
714 p.begin_group(step, name + '(')
720 p.begin_group(step, name + '(')
715 for idx, arg in enumerate(getattr(obj, 'args', ())):
721 for idx, arg in enumerate(getattr(obj, 'args', ())):
716 if idx:
722 if idx:
717 p.text(',')
723 p.text(',')
718 p.breakable()
724 p.breakable()
719 p.pretty(arg)
725 p.pretty(arg)
720 p.end_group(step, ')')
726 p.end_group(step, ')')
721
727
722
728
723 #: the exception base
729 #: the exception base
724 try:
730 try:
725 _exception_base = BaseException
731 _exception_base = BaseException
726 except NameError:
732 except NameError:
727 _exception_base = Exception
733 _exception_base = Exception
728
734
729
735
730 #: printers for builtin types
736 #: printers for builtin types
731 _type_pprinters = {
737 _type_pprinters = {
732 int: _repr_pprint,
738 int: _repr_pprint,
733 float: _repr_pprint,
739 float: _repr_pprint,
734 str: _repr_pprint,
740 str: _repr_pprint,
735 tuple: _seq_pprinter_factory('(', ')', tuple),
741 tuple: _seq_pprinter_factory('(', ')', tuple),
736 list: _seq_pprinter_factory('[', ']', list),
742 list: _seq_pprinter_factory('[', ']', list),
737 dict: _dict_pprinter_factory('{', '}', dict),
743 dict: _dict_pprinter_factory('{', '}', dict),
738
744
739 set: _set_pprinter_factory('{', '}', set),
745 set: _set_pprinter_factory('{', '}', set),
740 frozenset: _set_pprinter_factory('frozenset({', '})', frozenset),
746 frozenset: _set_pprinter_factory('frozenset({', '})', frozenset),
741 super: _super_pprint,
747 super: _super_pprint,
742 _re_pattern_type: _re_pattern_pprint,
748 _re_pattern_type: _re_pattern_pprint,
743 type: _type_pprint,
749 type: _type_pprint,
744 types.FunctionType: _function_pprint,
750 types.FunctionType: _function_pprint,
745 types.BuiltinFunctionType: _function_pprint,
751 types.BuiltinFunctionType: _function_pprint,
746 types.MethodType: _repr_pprint,
752 types.MethodType: _repr_pprint,
747
753
748 datetime.datetime: _repr_pprint,
754 datetime.datetime: _repr_pprint,
749 datetime.timedelta: _repr_pprint,
755 datetime.timedelta: _repr_pprint,
750 _exception_base: _exception_pprint
756 _exception_base: _exception_pprint
751 }
757 }
752
758
753 try:
759 try:
754 _type_pprinters[types.DictProxyType] = _dict_pprinter_factory('<dictproxy {', '}>')
760 _type_pprinters[types.DictProxyType] = _dict_pprinter_factory('<dictproxy {', '}>')
755 _type_pprinters[types.ClassType] = _type_pprint
761 _type_pprinters[types.ClassType] = _type_pprint
756 _type_pprinters[types.SliceType] = _repr_pprint
762 _type_pprinters[types.SliceType] = _repr_pprint
757 except AttributeError: # Python 3
763 except AttributeError: # Python 3
758 _type_pprinters[slice] = _repr_pprint
764 _type_pprinters[slice] = _repr_pprint
759
765
760 try:
766 try:
761 _type_pprinters[xrange] = _repr_pprint
767 _type_pprinters[xrange] = _repr_pprint
762 _type_pprinters[long] = _repr_pprint
768 _type_pprinters[long] = _repr_pprint
763 _type_pprinters[unicode] = _repr_pprint
769 _type_pprinters[unicode] = _repr_pprint
764 except NameError:
770 except NameError:
765 _type_pprinters[range] = _repr_pprint
771 _type_pprinters[range] = _repr_pprint
766 _type_pprinters[bytes] = _repr_pprint
772 _type_pprinters[bytes] = _repr_pprint
767
773
768 #: printers for types specified by name
774 #: printers for types specified by name
769 _deferred_type_pprinters = {
775 _deferred_type_pprinters = {
770 }
776 }
771
777
772 def for_type(typ, func):
778 def for_type(typ, func):
773 """
779 """
774 Add a pretty printer for a given type.
780 Add a pretty printer for a given type.
775 """
781 """
776 oldfunc = _type_pprinters.get(typ, None)
782 oldfunc = _type_pprinters.get(typ, None)
777 if func is not None:
783 if func is not None:
778 # To support easy restoration of old pprinters, we need to ignore Nones.
784 # To support easy restoration of old pprinters, we need to ignore Nones.
779 _type_pprinters[typ] = func
785 _type_pprinters[typ] = func
780 return oldfunc
786 return oldfunc
781
787
782 def for_type_by_name(type_module, type_name, func):
788 def for_type_by_name(type_module, type_name, func):
783 """
789 """
784 Add a pretty printer for a type specified by the module and name of a type
790 Add a pretty printer for a type specified by the module and name of a type
785 rather than the type object itself.
791 rather than the type object itself.
786 """
792 """
787 key = (type_module, type_name)
793 key = (type_module, type_name)
788 oldfunc = _deferred_type_pprinters.get(key, None)
794 oldfunc = _deferred_type_pprinters.get(key, None)
789 if func is not None:
795 if func is not None:
790 # To support easy restoration of old pprinters, we need to ignore Nones.
796 # To support easy restoration of old pprinters, we need to ignore Nones.
791 _deferred_type_pprinters[key] = func
797 _deferred_type_pprinters[key] = func
792 return oldfunc
798 return oldfunc
793
799
794
800
795 #: printers for the default singletons
801 #: printers for the default singletons
796 _singleton_pprinters = dict.fromkeys(map(id, [None, True, False, Ellipsis,
802 _singleton_pprinters = dict.fromkeys(map(id, [None, True, False, Ellipsis,
797 NotImplemented]), _repr_pprint)
803 NotImplemented]), _repr_pprint)
798
804
799
805
800 if __name__ == '__main__':
806 if __name__ == '__main__':
801 from random import randrange
807 from random import randrange
802 class Foo(object):
808 class Foo(object):
803 def __init__(self):
809 def __init__(self):
804 self.foo = 1
810 self.foo = 1
805 self.bar = re.compile(r'\s+')
811 self.bar = re.compile(r'\s+')
806 self.blub = dict.fromkeys(range(30), randrange(1, 40))
812 self.blub = dict.fromkeys(range(30), randrange(1, 40))
807 self.hehe = 23424.234234
813 self.hehe = 23424.234234
808 self.list = ["blub", "blah", self]
814 self.list = ["blub", "blah", self]
809
815
810 def get_foo(self):
816 def get_foo(self):
811 print("foo")
817 print("foo")
812
818
813 pprint(Foo(), verbose=True)
819 pprint(Foo(), verbose=True)
General Comments 0
You need to be logged in to leave comments. Login now