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