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