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