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