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