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