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